Vue2中组件的通信方式总结
文章目录
- 前言
- 一、为什么组件之间需要通信
- 二、父子通信
- 1.Props(父传子)
- 2.$emit+自定义属性(子传父)
- 三、兄弟组件通信
- 通过共同的父组件(Event Bus 模式)
- 四、跨层级组件通信
- Provide / Inject
- 五、Vuex 状态管理
- Store 配置
- 在组件中使用
- 六、5. 其他通信方式
- $refs
- $parent / $children
- $attrs / $listeners
- 总结
前言
在复习vue2的过程中,我发现我对组件之间的通信方式的知识点有所遗忘,写一篇博客总结一下
一、为什么组件之间需要通信
组件通信就是组件和组件之间的数据传递,因为组件和组件之间的数据是独立的,无法直接访问其他组件的数据,想用其他组建的数据需要用到组件通信。
二、父子通信
1.Props(父传子)
<!-- 父组件 -->
<template><ChildComponent :message="parentMessage" :count="count" />
</template><script>
export default {data() {return {parentMessage: 'Hello from parent',count: 0}}
}
</script><!-- 子组件 -->
<template><div><p>{{ message }}</p><p>{{ count }}</p></div>
</template><script>
export default {props: {message: String,count: Number}
}
</script>
2.$emit+自定义属性(子传父)
<!-- 子组件 -->
<template><button @click="sendMessage">发送消息给父组件</button>
</template><script>
export default {methods: {sendMessage() {this.$emit('message-from-child', 'Hello from child!')}}
}
</script><!-- 父组件 -->
<template><ChildComponent @message-from-child="handleChildMessage" />
</template><script>
export default {methods: {handleChildMessage(message) {console.log(message) // 'Hello from child!'}}
}
</script>
三、兄弟组件通信
通过共同的父组件(Event Bus 模式)
// event-bus.js
import Vue from 'vue'
export const EventBus = new Vue()// 组件 A - 发送事件
EventBus.$emit('data-shared', data)// 组件 B - 接收事件
EventBus.$on('data-shared', (data) => {// 处理数据
})
四、跨层级组件通信
Provide / Inject
<!-- 祖先组件 -->
<template><div><ParentComponent /></div>
</template><script>
export default {provide() {return {theme: 'dark',user: {name: 'John',age: 25}}}
}
</script><!-- 后代组件 -->
<template><div :class="`theme-${theme}`">{{ user.name }}</div>
</template><script>
export default {inject: ['theme', 'user']
}
</script>
五、Vuex 状态管理
Store 配置
// store.js
import Vue from 'vue'
import Vuex from 'vuex'Vue.use(Vuex)export default new Vuex.Store({state: {count: 0,user: null},mutations: {increment(state) {state.count++},setUser(state, user) {state.user = user}},actions: {login({ commit }, user) {commit('setUser', user)}},getters: {isLoggedIn: state => !!state.user}
})
在组件中使用
<template><div><p>{{ count }}</p><p>{{ isLoggedIn }}</p><button @click="increment">增加</button><button @click="login">登录</button></div>
</template><script>
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'export default {computed: {...mapState(['count']),...mapGetters(['isLoggedIn'])},methods: {...mapMutations(['increment']),...mapActions(['login'])}
}
</script>
六、5. 其他通信方式
$refs
<template><ChildComponent ref="child" /><button @click="callChildMethod">调用子组件方法</button>
</template><script>
export default {methods: {callChildMethod() {this.$refs.child.someMethod()}}
}
</script>
$parent / $children
// 访问父组件
this.$parent.parentMethod()// 访问子组件
this.$children[0].childMethod()
$attrs / $listeners
<!-- 中间组件 -->
<template><GrandChild v-bind="$attrs" v-on="$listeners" />
</template><script>
export default {inheritAttrs: false
}
</script>
总结
组件通信是vue中常用的一个知识点,我们需要熟练掌握它。