vue组件之间的传值父传子、子传父、兄弟传兄弟说明。
父组件传值给子组件:
子组件嵌套在父组件内部,父组件给子组件传递一个标识,在子组件内部用props接收,子组件在模板里可以通过{{}}的形式进行使用。如果父组件给子组件传递的标识中含有—,子组件在接收时采用驼峰式接收。
- 父组件调用子组件;
- 添加自定义属性,属性名随便定义(但是不要定义id,class等);
- 属性值为你需要传递的值(这个值可以是变量,如果是变量则使用绑定属性);
- 定义子组件的地方, 添加一个选项props;
- props中的元素就是父元素提供的属性名;
在子组件内部就可以直接使用父组件中定义的属性名,得到传递过来的属性值;
父组件 list.vue:
<template>
<table :parentMsg='parentMsg'></table>
</template>
<script>
import table from "./table.vue";
export default {
name: "list",
components: {
table
},
data() {
return {
parentMsg: "parent传值"
};
}
};
</script>
子组件 table.vue:
<template>
<div>
子组件接收的父组件的值:{{parentMsg}}
</div>
</template>
<script>
export default {
name: "table",
props: {
parentMsg: {
type: String,
default: ""
}
},
// props:['parentMsg'], props也可以采用数组方式接收
data() {
return {};
}
};
</script>
子组件传值给父组件:
子组件通过$emit事件传值给父组件。
- 定义好一个事件标识,parent-clk(相当于定义好了通道);
- 通过this.$emit(‘parent-clk’, 传递的值);
- 父组件调用子组件的地方,执行这个事件;
- 父组件中事件得到的就是子组件传递给父组件的值。
子组件 table.vue:
<template>
<div>
<button @click="setSonData">点击我传值给父组件</button>
</div>
</template>
<script>
export default {
name: "table",
data() {
return {
sonMsg:'son传值'
};
},
methods:{
setSonData(){
const vm = this;
vm.$emit('getSonData',vm.sonMsg);
}
}
};
</script>
父组件 list.vue:
<template>
<table @getSonData='getSonData'></table>
</template>
<script>
import table from "./table.vue";
export default {
name: "list",
components: {
table
},
data() {
return {
parentMsg: "parent传值"
};
},
methods:{
getSonData(val){
// val就是子组件传递给父组件的值
console.log(val); //son传值
}
}
};
</script>
兄弟组件之间传值:(非父子组件传值)
兄弟组件之间传值我个人觉得算是组件传值中最麻烦的一个。我们只要定义好一方负责监听一方负责触发即可,他们之间相互传值依据的是中间事件new vue。
- 创建bus.js,一个父组件,两个子组件;
- 父组件中引入子组件,子组件中引入bus.js;
- 使用 $on 负责监听事件, $emit 负责触发事件 并传递参数。
bus.js:
import Vue from 'Vue';
export default new Vue;
如果要实现query传值给table,table子组件将获取的值传值给query。
query.vue中定义一个事件sendData,通过sendData事件使用$emit绑定另一个事件querytotable传参,table.vue通过 $on监听querytotable事件获取传递过来的参数。具体实现如下:
query.vue:
<template>
<button @click="sendData"></button>
</template>
<script>
import bus from "./bus.js";
export default {
name: "query",
data() {
return {};
},
methods: {
sendData(val) {
bus.$emit("querytotable", val);
}
},
mounted() {
//监听table组件传值
bus.$on("tabletoquery", val => {
console.log(val);
});
}
};
</script>
table.vue:
<script>
import bus from "./bus.js";
export default {
name: "table",
data() {
return {};
},
mounted() {
bus.$on("querytotable", val => {
console.log(val);// query所传值
// 获取的值传值给query组件
bus.$emit("tabletoquery", val);
});
}
};
</script>
注: 如果AB组件有两次交互,就会有四次事件,如果做三次事件就会有六次事件,其实最麻烦的不是他们之间的传值,而是定义他们之间的事件名称,如果没有一套完备定义事件名称的规则,会无端的增加项目开发的周期,降低了开发效率,代码的耦合度会增加,维护性也低了。所以不建议使用。
解决办法:
在main.js中
vue.prototype.$bus = new Vue()
在原型上扩展一个$bus,
不单独创建bus文件,
通过this.$bus.$on()进行使用。
项目中使用发现兄弟组件传值监听是同步的,如果遇到数据处理需要异步请求获取,此刻会出问题。根据实际情况解决。
父子通信:父向子传递数据是通过 props,子向父是通过 events( $emit);通过父链 / 子链也可以通信( $parent / $children);ref 也可以访问组件实例;provide / inject API; $attrs/ $listeners.
兄弟通信:bus;Vuex
跨级通信:bus;Vuex;provide / inject API、 $attrs/ $listeners