这是我参与8月更文挑战的第17天,活动详情查看:8月更文挑战
给组件绑定原生事件(.native)
要在一个组件的根元素上直接监听一个原生事件,可以使用 v-on 的 .native
修饰符。
<child content="hello VUE" @click="handleClick"></child>
如果不写.native
点击事件是无效的。原因是子组件的点击事件是原生事件,而父组件中的点击事件是自定义事件。
正确写法:<child content="hello VUE" @click.native="handleClick"></child>
非父子组件间的传值
当项目中出现很复杂的数据传递时(主要是同级组件之间需要进行数据传递的话,如果单纯地靠一层层地传递,可能会会让项目变得复杂),所以光靠Vue框架是解决不了复杂数据的传递,此时我们需要引入一些工具或者设计模式来解决Vue之中组件间复杂的数据传递。VUE对于非父子组件间的数据传递提供了两种方案:
- 借助Vue官方提供的一个数据层的框架——Vuex;
- 发布订阅模式(又称为:总线机制/Bus/观察者模式)。
通信数据比较简单时,可以采用第二种方案,当项目比较庞大,采用
Vuex
。
这里我们主要介绍第二种模式,主要步骤共分为三步:
1. 创建事件总线;
2. 使用$emit方式传值;
3. 使用$on方式接收值(需要写在mounted里面)
具体实现:
场景需求: 点击组件A,改变组件B的值,反之亦然。(为方便实验,以同一个组件为例);
方法实现: 首先实现组件渲染,再实现点击显示数据,最后实现兄弟组件的传值。
// 在vue原型上定义一个bus属性,为vue实例
Vue.prototype.bus = new Vue()
var child = {
// 父子组件传值符合单向数据流规则
data: function() {
return {
childContent: this.content
}
},
props: {
content: String
},
template: '<div @click="handleClick">{{childContent}}</div>',
methods: {
handleClick: function() {
//事件广播
this.bus.$emit('change', this.childContent)
}
},
//在模板编译完成后执行
mounted: function() {
let _this = this
//事件订阅
this.bus.$on('change',function(msg) {
_this.childContent = msg
})
}
}
复制代码
关键点解析:
- 解析
this.bus.$emit('change', this.content)
:
this.bus
指的就是Vue.prototype.bus = new Vue ()
上挂载的 bus
,同时bus
作为Vue实例,有其方法,这里为 $emit
,以此向外触发事件并同时 携带要传递的内容数据
- 解析
Vue .prototype.bus
:
在Vue 的prototype
上挂载了一个bus
的属性,该bus
属性指向一个 Vue 的实例。在之后,只要调用 new.Vue
或者创建组件时,每个组件上都会有bus
这个属性(为什么?因为每个Vue实例和组件都是通过 Vue 这个类进行创建,而在Vue的prototype
挂载一个bus的属性,都指向同一个 Vue 的实例)。
- 由于两组件几乎同时加载,因此事件订阅
$on
放在mouted
中即可。