天天看点

vue中父子组件之间的通信方式

1、属性往下 事件往上

思路: 父组件把事件函数通过事件绑定的方式传递给子组件 让子组件调用并传递参数

<div id="app">
    <coma></coma>
</div>
<template id="tpl">
    <form>
        <h1>我是组件标题---{{title}}</h1>
        <child1 :change='change'></child1> <!-- 1 给子组件绑定一个属性 把父组件的函数传递过去--->
    </form>
</template>
           
// 把事件传递给子组件
// 定义组件
Vue.component("coma", {
    template: `#tpl`,
    data: function () {
        return {
            title: ""
        }
    },
    components: {
        // 定义子组件
        child1: {
            template: `<div><input v-model='inp' type='text' @input="a"></div>`, // 3 子组件绑定一个事件
            data: function () {
                return {
                    inp: "我是子组件的内容"
                }
            },
            props: ["change"], // 2 子组件接受这个函数
            methods: {
                a: function () {
                    // 4 调用父组件的方法 把内容给父组件的函数传递过去
                    this.change(this.inp)
                }
            }

        },
    },
    // 父组件的方法
    methods: {
        change: function (data) {
            this.title = data;
            console.log(this.title)
        }
    }
})


new Vue({
    el: "#app",
    data: {

    },
})
           

2、父组件绑定事件 子组件this.$emit

<div id="app">
     <coma></coma>
</div>
<template id="tpl">
     <form>
         <h1>我是组件标题---{{title}}</h1>
         <child1 @change="change"></child1>  // 1 在父组件里 给子组件绑定一个自定义事件
    </form>
</template> 
           
// 把事件传递给子组件
    // 定义组件
    Vue.component("coma", {
        template: `#tpl`,
        data: function () {
            return {
                title: ""
            }
        },
        components: {
            // 定义子组件1
            child1: {
                template: `<div><input v-model='inp' type='text' @input="a"></div>`,
                data: function () {
                    return {
                        inp: "我是子组件的内容"
                    }
                },
                methods: {
                    a: function () {
                        // 2 子组件内通过this.$emit进行事件的触发并传递参数
                        this.$emit("change", this.inp);
                    }
                }

            },
        },
        // 父组件的方法
        methods: {
            change: function (childMsg) {
                //    console.log("这里是父组件的一个函数", childMsg)
                this.title = childMsg;
            }
        }
    })
	new Vue({
	     el: "#app" 
	})
           

3、事件总线

所谓的事件总线是Vue对观察者模式的一个改进。

用法与观察者模式一模一样。

(1)初始化一个新的Vue实例

(2)使用它在父组件的mounted的生命周期函数内去注册

Vue.component("父组件", {
   mounted: function() {
      bus.$on("xxx", () => {
        // 这里用什么函数 要取决于你的功能中是否要使用外部的this 
      })
   }  
})
           

(3)在子组件中触发这个父组件绑定的自定义事件

Vue.component("父组件", {

  	components: {
  		"子组件": {
  			methods: {
  				aaa: function() {
  					bus.$emit("xxx", "参数")
  				}
  			}
  		}
  	
  	}

})
           

4、关系链

我们如果把组件视作节点的话,原生中,获取节点可以通过节点关系属性。 parentNode、childNodes、nextSibling、previousSibling等属性。

在Vue中,也有对应的组件关系。我们称之为关系链。

获取父组件 this.$parent

获取子组件集合 this.$children; ps: 集合加下标获取对应的组件

获取根组件 this.$root

5、ref属性

我们可以给任意的组件或者元素 绑定ref属性 绑定之后我们就可以在对应的层级中通过this.$refs属性进行获取

<div id="app">
    <div ref="a"></div>
    <button @click="click">点我获取div元素</button>
    <father ref="f" ></father>
</div>
           

获取:

var vue= new Vue({
    methods: {
        click() {
           console.log(this.$refs)
        }
    }
})
           

当事件触发时:

vue中父子组件之间的通信方式

总结:

由父组件向子组件传值: 通过props进行通信;

由子组件向父组件传值:关键在于$emit的应用。

继续阅读