VUE中组件之间的通信方式
目录父子组件之间的通信方式1.props+$emit()3.$parent+$children4.provide+inject5.$attrs+$listeners6.ref+$refs(备注视频代码学习来自:重要!父子组件通信的方式有哪几种?【Vue面试题】_哔哩哔哩_bilibili)父子组件之间的通信方式1.props+$emit()1.父组件通过props向子组件传递数据(在子组件中用pr
目录
(备注视频代码学习来自:重要!父子组件通信的方式有哪几种?【Vue面试题】_哔哩哔哩_bilibili)
一、父子组件之间的通信方式
1.props+$emit()
1.父组件通过props向子组件传递数据(在子组件中用props接收)
2.子组件通过$emit()向父组件传递数据或事件,如在子组件中自定义事件changeMessage,携带信息'bye’, 然后在父组件中通过v-on监听这个事件
parent.vue
<template>
<div id="app">
<h1>父亲</h1>
<p>{{message}}</p>
<child :message="message" @changeMessage="message =$event"> </child>
</div>
</template>
<script>
import Child from "./child.vue"
export default {
data () {
return {
message: 'hello'
}
},
components: {
Child
},
methods: {
changeMeaasge () {
this.message = 'Bye'
}
}
}
</script>
child.vue
<template>
<div>
<h1>孩子</h1>
<p>{{message}}</p>
<button @click="handleClick"> 按钮</button>
</div>
</template>
<script>
export default {
props: ['message'],
methods: {
handleClick () {
this.$emit('changeMessage', 'Bye')
}
}
}
</script>
运行后如下,点击按钮,父亲孩子下面的hello都会变成bye。
2.通过回调函数(callback)
parent.vue(将changeMsgFn作为另外一个props传给子组件)
<template>
<div id="app">
<h1>父亲</h1>
<p>{{message}}</p>
<child :message="message" :changeMsgFn="changeMeaasge"> </child>
</div>
</template>
<script>
import Child from "./child.vue"
export default {
data () {
return {
message: 'hello'
}
},
components: {
Child
},
methods: {
changeMeaasge () {
this.message = 'Bye'
}
}
}
</script>
child.vue
<template>
<div>
<h1>孩子</h1>
<p>{{message}}</p>
<button @click="changeMsgFn"> 按钮</button>
</div>
</template>
<script>
export default {
props: ['message', 'changeMsgFn'],
}
</script>
3.$parent+$children
1.父组件通过$children访问子组件
2.子组件通过$parent访问父组件
parent.vue
<template>
<div id="app">
<h1>父亲</h1>
<p>{{message}}</p>
<button @click="changeChildNumber">按钮</button>
<child></child>
</div>
</template>
<script>
import Child from "./child.vue"
export default {
data () {
return {
message: 'hello'
}
},
components: {
Child
},
methods: {
changeChildNumber () {
this.$children[0].number = 50
}
}
}
</script>
child.vue
<template>
<div>
<h1>孩子</h1>
<p>{{number}}</p>
<p>{{parentMessage}}</p>
</div>
</template>
<script>
export default {
data () {
return {
number: 10
}
},
computed: {
parentMessage () {
return this.$parent.message
}
}
}
</script>
(点击按钮后子组件中的数据10变为50)
4.provide+inject
parent.vue
<template>
<div id="app">
<h1>父亲</h1>
<child></child>
</div>
</template>
<script>
import Child from "./child.vue"
export default {
components: {
Child
},
provide: {
message: 'Hello'
}
}
</script>
child.vue
<template>
<div>
<h1>孩子</h1>
<p>{{message}}</p>
</div>
</template>
<script>
export default {
inject: ['message']
}
</script>
5.$attrs+$listeners
parent.vue
<template>
<div id="app">
<h1>父亲</h1>
<p>姓名:{{name}}</p>
<p>年龄:{{age}}</p>
<child :name="name" :age="age" @changeName='changeName'></child>
</div>
</template>
<script>
import Child from "./child.vue"
export default {
components: {
Child
},
data () {
return {
name: 'pipi',
age: 1
}
},
methods: {
changeName () {
this.name = 'wuyi'
}
}
}
</script>
child.vue
<template>
<div>
<h1>孩子</h1>
<button @click="$listeners.changeName">按钮</button>
<grand-child v-bind="$attrs"></grand-child>
</div>
</template>
<script>
import GrandChild from './GrandChild.vue'
export default {
components: {
GrandChild
}
}
</script>
GrandParent.vue
<template>
<div>
<h1>孙子</h1>
<p>姓名:{{$attrs.name}}</p>
<p>年龄:{{$attrs.age}}</p>
</div>
</template>
<script>
export default {
}
</script>
6.ref+$refs
parent.vue
<template>
<div id="app">
<h1>父亲</h1>
<child ref="childComp"></child>
<button @click="changeName">按钮</button>
</div>
</template>
<script>
import Child from "./child.vue"
export default {
components: {
Child
},
methods: {
changeName () {
console.log('点击前', this.$refs.childComp.age);
this.$refs.childComp.changeAge();
console.log('点击后', this.$refs.childComp.age);
}
}
}
</script>
child.vue
<template>
<div>
<h1>孩子</h1>
</div>
</template>
<script>
export default {
data () {
return {
age: 20
}
},
methods: {
changeAge () {
this.age = 50;
}
}
}
</script>
每种通信方式还需要继续学习,各自优缺点局限性等....
二、兄弟组件之间的通信方式
1.子传值到父,再由父传值到子
<template>
<div id="app">
<h1>父亲</h1>
<p>name:{{name}}</p>
<hr>
<child11 :name="name" @ChildOneClick="handleParentClick" />
<hr>
<child22 :name="name" />
</div>
</template>
<script>
import child11 from './child11.vue'
import child22 from './child22.vue'
export default {
data () {
return {
name: 'pipiwuyi'
}
},
methods: {
handleParentClick (name) {
this.name = name;
}
},
components: {
child11,
child22,
},
}
</script>
child11.vue
<template>
<div>
<h1>孩子1</h1>
<p>name:{{name}}</p>
<button @click="handleChildOneClick">按钮</button>
</div>
</template>
<script>
import { eventBus } from '../main'
export default {
props: ['name'],
methods: {
handleChildOneClick () {
this.$emit('ChildOneClick', 'hui')
}
}
}
</script>
child22.vue
<template>
<div>
<h1>孩子2</h1>
<p>name:{{name}}</p>
</div>
</template>
<script>
export default {
props: ['name']
}
</script>
2.事件总线
new一个新的vue实例并导出,子组件都引入,子组件1$emit出去,子组件2$on监听
main.js
import Vue from 'vue'
import App from './App.vue'
export const eventBus = new Vue(); //创建实例,并导出
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
parent.vue
<template>
<div id="app">
<h1>父亲</h1>
<p>name:{{name}}</p>
<hr>
<Child1 :name="name" @ChildOneClick="handleParentClick" />
<hr>
<Child2 :name="name" />
</div>
</template>
<script>
import Child1 from './Child1.vue'
import Child2 from './Child2.vue'
export default {
data () {
return {
name: 'pipiwuyi'
}
},
methods: {
handleParentClick (name) {
this.name = name;
}
},
components: {
Child1,
Child2,
},
}
</script>
child1.vue
<template>
<div>
<h1>孩子1</h1>
<p>name:{{myName}}</p>
<button @click="handleChildOneClick">按钮</button>
</div>
</template>
<script>
import { eventBus } from '../main'
export default {
props: ['name'],
data () {
return {
myName: this.name
}
},
methods: {
handleChildOneClick () {
// this.$emit('ChildOneClick', 'hui')
this.myName = 'hui';
eventBus.$emit('ChildOneClick', 'hui')//eventBus是vue的实例,存在$emit的方法
}
}
}
</script>
child2.vue
<template>
<div>
<h1>孩子2</h1>
<p>name:{{myName}}</p>
</div>
</template>
<script>
import { eventBus } from '../main'
export default {
props: ['name'],
data () {
return {
myName: this.name
}
},
created () {
eventBus.$on('ChildOneClick', (name) => {
this.myName = name;
})
}
}
</script>
点击按钮,两个子组件中的内容改变,父组件中不变
更多推荐
所有评论(0)