Vue2.x 组件间通信方式(9种)
1. props父传子
props使子组件可读取父组件的数据
2. emit子传父
vm.$emit触发方法/发送数据
-
父组件
<!--v-on:sendFatherData="getSonData"的语法糖--> <son @sendFatherData="getSonData"/> /** * 定义事件 */ getSonData(sonData) { console.log(sonData); }
-
子组件
<button @click="send">触发父组件方法</button> send() { /* 参数1:定义函数名 参数2:数据 基本数据或者对象 */ this.$emit("sendFatherData", "数据1231312"); }
3. bus公共事件总线
-
在main.js给当前vue绑定一个vue实例
Vue.prototype.$bus = new Vue();
-
组件A定义函数
created(){ this.$bus.$on("defFunction",data=>{ console.log(data); }) }
-
组件B触发函数
<button @click="clickMethodByBus">通过事件总线触发方法</button> clickMethodByBus() { let data = "基本数据类型、对象";//传递过程不会转换数据类型 this.$bus.$emit("defFunction",data); }
4. $parent
//读取父数据、调用父方法
this.$parent.xxx
5. ref 和 refs
//父组件
<son ref="son1"/>
//读取子数据、调用子方法
this.$refs.son1.xxx
6. Storage
localStorage.setItem('key', 'vaule');
localStorage.getItem('key');
localStorage.removeItem('key');
// 移除所有
localStorage.clear();
7. Vuex
index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// 创建一个新的 store 实例
export default new Vuex.Store({
state () {
return {
count: 0
}
},
mutations: {
increment (state,num) {
state.count+=num;
}
}
})
使用vuex
methods: {
increment() {
//读取store数据this.$store.state.xxx
console.log(this.$store.state.count);
//修改store数据,参数2 data可以为任意数据类型、对象
this.$store.commit('increment',data)
}
}
8. provide/inject
// 父级组件提供 'foo'
var Provider = {
provide: {
foo: 'bar'
},
// ...
}
// 子组件注入 数据'foo'
var Child = {
inject: ['foo'],
created () {
//读取数据foo数据
console.log(this.foo) // => "bar"
}
// ...
}
9. $attrs/$listeners
-
父组件
<!--v-on:sendFatherData="getSonData"的语法糖--> <son @sendFatherData="getSonData" :fatherData="fatherData"/> data() { return { fatherData: "父数据" } } methods: { /** * 定义事件 */ getSonData(sonData) { console.log(sonData); } }
-
子组件
<sun v-bind="$attrs" v-on="$listeners"/>
-
孙组件
<button @click="send">触发父组件方法</button> props: { fatherData: { type: String, default: "" } }, send() { /* 参数1:定义函数名 参数2:数据 基本数据或者对象 */ this.$emit("sendFatherData", "数据1231312"); }
常见场景
父子组件通信
(1) 子组件渲染的时候–>父组件将值传到–>子组件(使用props)
(2) 某个时间子组件触发方法A–>子组件中获取父组件数据(使用this.$parent)
某个时间可以是创建子组件的时候,如果是创建子组件的时候,将方法A放在子组件的create函数
(3) 父组件方法触发 --> 将父组件的值传递到子组件(使用this.$ref)
(4) 父组件方法触发–>导致–>子组件方法触发(使用this.$ref)
(5) 子组件方法触发–>(触发父组件方法/将数据传递–>到父组件)【(使用this.$emit)】
sendToFather() {
this.$emit("getSonData",this.value)
}
(6)父组件方法触发–>(父组件获取子组件的值)【(使用this.$ref)】
2. 兄弟组件通信
(1)将B的数据传递给C
(a) B组件主动给(给的时间由可以放在生命周期函数或者绑定鼠标事件上决定)
- B组件–>this.$emit–>A组件–>props–>C组件
- B组件
this.$parent.$refs.son_c.value = this.sonBValue
(b) C组件主动获取
this.sonBValue = this.$parent.$refs.son_c.value
(2)事件总线
(a) 在main.js给当前vue绑定一个vue实例)
(b) B组件内定义事件
<button @click="clickBortherMethodByBus">通过事件总线触发兄弟组件C的方法/或者传值</button>
clickBortherMethodByBus() {
this.$bus.$emit("clickBorther2","使用事件总线");
}
(c) C组件内监听事件
mounted () {
this.$bus.$on("clickBorther2",(value)=> {
this.sonCValue = value;
});
}
3. 祖孙组件通信
(1)使用props和$emit可以使用v-bind="$attrs"和v-on="$listeners",子组件中可以之间传递,不用在子组件中接收一次
<grand-son v-bind="$attrs" v-on="$listeners"></grand-son>