【VUE】.native修饰符和非父子组件间的传值

507 阅读2分钟

这是我参与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中即可。