父到子 props
先定义一个子组件,在组件中注册props,这个是信使,用来与父组件通信
child.vue
中
<template>
<div>
<div>{{message}}(子组件)</div>
</div>
</template>
<script>
export default {
props: {
message: String //定义传值的类型<br> }
}
</script>
<style>
</style>
在父组件中,引入子组件,并传入子组件内需要的值
father.vue
中
<template>
<div>
<div>父组件</div>
<child :message="parentMsg"></child>
</div>
</template>
<script>
import child from './child' //引入child组件
export default {
data() {
return {
parentMsg: '这是在父组件中定义的消息' //在data中定义需要传入的值
}
},
components: {
//使用子组件
child
}
}
</script>
<style>
</style>
这种方式只能由父向子传递,子组件不能更新父组件内的data
子到父
子组件 child.vue
<template>
<div>
子组件:
<span>{{childValue}}</span>
<!-- 定义一个子组件传值的方法 -->
<input type="button" value="点击我将向父组件发送数据" @click="childClick">
</div>
</template>
<script>
export default {
data () {
return {
childValue: '我是子组件的数据'
}
},
methods: {
childClick () {
// childByValue是在父组件on监听的方法
// 第二个参数this.childValue是需要传的值
this.$emit('childByValue', this.childValue)
}
}
}
</script>
父组件 father.vue
注意:是v-on:childByValue="receiveChild"
而不是v-on:childByValue="receiveChild(data)"
这里不需要有参数,v-on
可以缩写为@
<template>
<div>
父组件:
<span>{{name}}</span>
<br>
<br>
<!-- 引入子组件 父组件自定义一个childByValue事件,用于给子组件触发-->
<child v-on:childByValue="receiveChild"></child>
</div>
</template>
<script>
//引入
import child from './child'
export default {
components: {
child
},
data () {
return {
name: ''
}
},
methods: {
//接收子组件事件的函数
receiveChild: function (childValue) {
// childValue就是子组件传过来的值
this.name = childValue
}
}
}
</script>
非父子
官网说明
非父子关系的两个组件之间也需要通信。在简单的场景下,可以使用一个空的 Vue 实例作为事件总线:
var bus = new Vue()
// 触发组件 A 中的事件
bus.$emit('id-selected', 1)
// 在组件 B 创建的钩子中监听事件
bus.$on('id-selected', function (id) {
// ...
})
实例
实例目录组件树目录
假设 bb 组件里面有个按钮,点击按钮,把 123 传递给 aa 组件
// 根组件(this.$root)
new Vue({
el: '#app',
router,
render: h => h(App),
data: {
// 空的实例放到根组件下,所有的子组件都能调用
Bus: new Vue()
}
})
bb 组件内调用事件触发↓
<button @click="submit">提交<button>
methods: {
submit() {
// 事件名字自定义,用不同的名字区别事件
this.$root.$emit('eventName', 123)
}
}
aa 组件内调用事件接收↓
// 当前实例创建完成就监听这个事件
created(){
this.$root.$on('eventName', value => {
this.print(value)
})
},
methods: {
print(value) {
console.log(value)
}
},
// 在组件销毁时别忘了解除事件绑定
beforeDestroy() {
this.$root.Bus.$off('eventName')
},
组件销毁的使用$.off取消资格绑定 ,不然会触发多次。
官方推荐的eventbus 解决方案可能存在缺陷, 在数据传递过程中,两个组件必须都已经被渲染过
在一个组件创建时的钩子函数中监听 某个事件,而在需要与其进行通信的组件中触发这个函数,同时交换数据。
当然,event bus 只适于某些不复杂的场景,在需要频繁进行组件通信的情况下,还是应该尽量使用 Vuex ,不仅使用上更加简单,同时数据流的流向也会相对清晰。