vue2.0 组件之间通信

概念

双向数据流:
父组件数据能传递到子组件,子组件接收数据,进行展示;此外子组件可以修改父组件中的数据

双向数据绑定的劣势:
它破环了单向数据流的简洁性, 这增加了分析数据时的难度
不要在子组件中,通过修改引用类型props中的数据,达到“父子组件数据同步”的需求!
这样会让数据流变得更加难以分析

父子之间通信(主要数据逻辑在父级完成)

父->子 : 组件标签上绑定自定义属性,挂载数据,子页面通过props获取
子->父:组件标签上绑定这个自定义事件,子组件中通过$emit('自定义事件'),触发自定义事件

组件通信方式很多


组件数据通信

实例如下:

1.父级中

父级内容,子级在当前组件中
//父级数据 data: function() { return { data1: '挂载在 组件上的数据 ' } }, methods: { changemesfn2handle: function(val) { console.log(val); //新的数据 this.data1 = '挂载在 组件上的数据 被改变了~~~~~~~~~~~~~~~~ '; } }

2.子组件中

我是子组件Mytag {{parentdata}}

按钮
props: { parentdata: { type: String, default: '默认值' } }, methods: { changeMes2: function() { this.$emit("changemesfn2",'新的数据'); } }
父子之间通信(主要数据逻辑在子级完成)

鉴于组件复用的原理,数据逻辑应该在父级来做操作

1.父级中

子组件直接修改父级
data: function() { return { yourdata:'挂载在 组件上的数据' } }

2.子组件中

我是子组件Mytag2
{{ fathermes }}

按钮
props: { fathermes: { type: String, default: 'hello' } }, methods: { changesyncfn: function() { this.$emit('update:fathermes', '数据改变了~~~~~~'); } }
父子之间通信(子组件在router-view中)

当子元素为router-view中的组件时候

1.父级

{{msg}}

methods: { changemeshandle: function() { this.msg = "挂载在的数据 从(子)改变(父)~~~~~~~~~~~~~~~~~~~~~~"; } }

2.子级router-view

改变父级内容

methods: {
    changeMes: function() {
        this.$emit("changemesfn");
    }
}

父子之间通信(通过v-model的方式传递数据)

v-model是 Vue的一个语法糖,在表单中,主要表现为:
在输入框、文本域中,v-bind:value="数据",v-on:input="事件处理"
在复选框,单选框中,v-bind:checked="布尔值",v-on:change="事件处理"

所以我们也可以借助v-model实现组件的数据传递
1.父组件内



data: function() {
    return {
        msg1: '我是父级数据~~~~~~~~'
    }
}

2.子组件

按钮

...
props: {
    value: {  //通过value接收数据
        type: String,
        default:"默认值"
    }
},
methods: {
    fn1: function() {
        this.$emit('input', '数据变化了');  //通过emit发送事件
    }
}
组件内快速数据传递

方式1原理:通过根实例作为媒介
vm.emit中的第二个参数
事件可以由vm.$emit触发

通过根实例$emit,$on实现快速通信
1.借助Vue的$root找到根组件上的Vue实例对象
2.通过$root.$emit发布事件,通过$root.$on接收事件
借助根实例

例:
组件1 输入框,添加内容,发送事件
组件2 接收内容,渲染到ul-li列表

1.组件1 (发送新增的内容)



methods: {
    addlist: function() {
        var _val = this.$refs.input1.value;
        this.$root.$emit('addlistfn', _val);
    }
}

2.组件2(接收内容,渲染到页面)

列表:
  • {{item}}
data: function() { return { arr: [] } }, created() { var that = this; this.$root.$on('addlistfn', function(val) { that.arr.push(val); console.log(this) //$parent undefined 根节点的Vue实例 console.log(this.$root == this) //true console.log(that) //$parent 存在 //当前组件页面的Vue实例 }); }

上面实现的方法是借助于根实例,
另外,也可以通过在入口文件中,对根实例添加插件,Vue原型上增加$eventBus属性,值为new Vue()
使用新的Vue实例来做
在main.js文件中

Vue.use({
  install(Vue){
    Vue.prototype.$eventBus = new Vue();
  }
})

事件总线(event bus)

将上面实现方式中的 $root 替换成 $eventBus 依然是可行的

这种方式的不足
1.操作事件总线中的组件越多,后续调试越麻烦
2.结果没有规则,不可调试

父组件获取子组件中数据 单向数据流

将ref挂载子组件上,父级通过$refs可以查找对应的组件,和上面的数据

ref 被用来给元素或子组件注册引用信息

1.引用信息将会注册在父组件的 $refs 对象上
2.如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素
3.如果用在子组件上,引用就指向组件实例:
因为 ref 本身是作为渲染结果被创建的,在初始渲染的时候你不能访问它们 - 它们还不存在!$refs 也不是响应式的

父组件中


 是"{{mess4sondata}}"


data: function() {
    return {
        mess4sondata: ''
    }
},
methods: {
    getsondata: function() {
        if (this.$refs.sonpage4.sondata) {
            this.mess4sondata = this.$refs.sonpage4.sondata
        };
    }
}

子组件中

子页面的数据:{{sondata}}

data: function() { return { sondata: '我是子页面数据' } }
祖先传递孙子组件 (provide/inject 单向数据流)

祖辈们传递到孙子辈组件中

provide/inject这对选项需要一起使用,
以允许一个祖先组件向其所有子孙后代注入一个依赖,
不论组件层次有多深,并在起上下游关系成立的时间里始终生效

组先

export default {
        name: "new",
        provide: {
            foo: 'hi'
        }
}

孙子辈们组件

{{foo}}

export default {
        name: "son1",
        inject: {
            foo: {
                type: String,
                default:'默认'
            }
        }
 }
单层父子通信

父级获取子级的属性以及方法

this.$refs.(子级上挂载的ref名).(属性名)
this.$refs.(子级上挂载的ref名).(方法名)

子级获取父级的属性以及方法

this.$parent.(属性名);
this.$parent.(方法名);

多层获取,可以通过不断寻找父级方式,进行封装,如下:

后代传递到祖先(单向数据流)

通过封装函数的方式,核心语法是:

$emit('自定义事件','数据');
$parent
$on('自定义事件',callback);

祖先 App.vue 根实例

created() {
    this.$on('aaa', function(val) {
        console.log(val);  //haha
    })
}

祖孙组件



data: function() {
    return {
        sondata1: 'haha'
    }
},
methods: {
    sendit: function() {

        function dispatch(that, eventName, data) {
            let parent = that.$parent    //传递this,以便能找到当前实例的$parent
            // 循环知道找到根实例
            while (parent) {
                parent.$emit(eventName, data)
                parent = parent.$parent
            }
        }
        //调用函数
        dispatch(this, 'aaa', this.sondata1);
    }
}

你可能感兴趣的:(vue2.0 组件之间通信)