vue组件通信大总结
文章目錄
- 1. props / $emit
- 2. sync / update
- 3. provide / inject
- 4. $attrs / $listeners
- 5. $children / $parent
- 6. ref / refs
- 7. Vuex
- 8. EventBus
- 9. localStorage/sessionStorage
- 總結
1. props / $emit
父組件給子組件添加屬性:msg="msg"傳值,子組件通過props:['msg']接收;
子組件可以通過this.$emit('changeMsg','Welcome')向父組件發送事件和數據,
父組件通過 @changeMsg="change" 監聽事件和傳遞過來的數據。
代碼
<!-- Parent.vue --> <template><div><son :msg="msg" @changeMsg="change" /></div> </template><script> import Son from './Son.vue' export default {name: 'Parent',data () {return {msg: '你好'}},components: {Son},methods: {change (msg) {this.msg = msg}} } </script> <!-- Son.vue --> <template><div>{{ msg }}<button @click="sendToParent">傳遞到Parent</button></div> </template><script> export default {name: 'Son',props: ['msg'],methods: {sendToParent () {this.$emit('changeMsg', 'Welcome')}} } </script>效果
適用于父子組件通信
2. sync / update
v2.3新增語法糖,會擴展成一個更新父組件綁定值的 v-on偵聽器;
<son :msg.sync="msg" />
子組件update:msg直接修改數據,父組件無需定義監聽事件來接收數據;
適合基本數據類型的傳遞和修改
<!-- Parent.vue --> <template><div><son :msg.sync="msg" /></div> </template><script> import Son from './Son.vue' export default {name: 'Parent',data () {return {msg: '你好'}},components: {Son} } </script> <!-- Son.vue --> <template><div>{{ msg }}<button @click="sendToParent">傳遞到Parent</button></div> </template><script> export default {name: 'Son',props: ['msg'],methods: {sendToParent () {this.$emit('update:msg', 'Welcome')}} } </script>3. provide / inject
父組件通過provide傳值,子組件通過inject:["msg"]接收,provide傳遞的數據, 不僅所有子組件都可以接收,所有后代組件均可以通過inject接收到。
<!-- Parent.vue --> <template><div><son /></div> </template><script> import Son from './Son.vue' export default {name: 'Parent',provide () {return {pdata: this}},data () {return {msg: '你好'}},components: {Son} } </script> <!-- Son.vue --> <template><div>{{ text }}<button @click="sendToParent">修改</button></div> </template><script> export default {name: 'Son',inject: ['pdata'],computed: {text () {return this.pdata.msg}},methods: {sendToParent () {this.pdata.msg = 'hello'}} } </script>4. $attrs / $listeners
v2.4新增
$attrs包含了父作用域中不作為prop 被識別 (且獲取) 的屬性綁定 (class 和 style 除外)。
$listeners 包含了父作用域中的 (不含 .native 修飾器的) v-on 事件監聽器,它可以通過 v-on="$listeners" 傳入內部組件。
效果
5. $children / $parent
父組件通過$children訪問子組件屬性和方法,子組件通過$parent訪問父組件屬性和方法, this.$children[0].age=2修改子組件數據,同理this.$parent.age=30 修改父組件數據。
<!-- Father.vue --> <template><div>Father Age: {{ age }}<button @click="updateSonAge">修改Son的Age</button><son /></div> </template><script> import Son from './Son' export default {name: 'Father',components: {Son},data () {return {age: 30}},methods: {updateSonAge () {this.$children[0].age = 15}} } </script> <!-- Son.vue --> <template><div>Son Age: {{ age }}<button @click="updateFatherAge">修改Father的Age</button></div> </template><script> export default {name: 'Son',data () {return {age: 10}},methods: {updateFatherAge () {this.$parent.age = 35}} } </script>效果
6. ref / refs
子組件綁定ref屬性,父組件通過this.$refs['xxx']訪問子組件,用法和 $children 相同。
this.$refs['son']===this.$children[0] //true
7. Vuex
vuex可以說是萬金油,因為它是vue的一個狀態管理庫,任何數據都可以存在這個庫里,缺點就是使用方法略微麻煩一點,優點就是不用管什么層級之間的傳遞數據都是可以的,而且是共享數據,所以還是要看有沒有必要使用這個方式,如果數據會在不同的層級,很多地方都需要使用或修改,且數據都是共享的,那么這種方式就是最好的。
<template><div id="app"><ChildA/><ChildB/></div> </template><script>import ChildA from './components/ChildA'import ChildB from './components/ChildB'export default {name: 'App',components: {ChildA, ChildB}} </script> <template><div id="childA"><h1>我是A組件</h1><button @click="transform">點我讓B組件接收到數據</button><p>{{BMessage}}</p></div> </template><script>export default {data() {return {AMessage: 'Hello,B組件,我是A組件'}},computed: {BMessage() {return this.$store.state.BMsg}},methods: {transform() {this.$store.commit('receiveAMsg', {AMsg: this.AMessage})}}} </script> <template><div id="childB"><h1>我是B組件</h1><button @click="transform">點我讓A組件接收到數據</button><p>{{AMessage}}</p></div> </template><script>export default {data() {return {BMessage: 'Hello,A組件,我是B組件'}},computed: {AMessage() {return this.$store.state.AMsg}},methods: {transform() {this.$store.commit('receiveBMsg', {BMsg: this.BMessage})}}} </script> /*** store.js */ import Vue from 'vue' import Vuex from 'vuex'Vue.use(Vuex)const state = {AMsg: '',BMsg: '' } const mutations = {receiveAMsg(state, payload) {state.AMsg = payload.AMsg},receiveBMsg(state, payload) {state.BMsg = payload.BMsg} }export default new Vuex.Store({state,mutations })8. EventBus
eventBus又稱為事件總線,在vue中可以使用它來作為溝通橋梁的概念, 就像是所有組件共用相同的事件中心,可以向該中心注冊發送事件或接收事件, 所有組件都可以通知其他組件。(維護困難,eventName起名字困難,不易維護,不及時注銷事件會產生各種問題,復雜項目中還是使用Vuex)
//新建一個Vue實例作為中央事件總線 let EventBus = new Vue(); //監聽事件 EventBus.$on('eventName', (val) => {//......do something }); //觸發事件 EventBus.$emit('eventName', 'this is a message.'); //移除事件 EventBus.$off('eventName', {})9. localStorage/sessionStorage
本地存儲,某些業務中使用較多,比如記住用戶token、用戶信息、系統設置等
window.localStorage.getItem(key)獲取數據,通過 window.localStorage.setItem(key,value) 存儲數據;
注意:value只能是字符串類型,需要用JSON.parse() / JSON.stringify()轉換
sessionStorage同理。
總結
| props / $emit | 最常用的父子組件通信 |
| sync/update | 父子組件基本數據類型,適用于子組件修改父組件數據 |
| provide/inject | 多層級傳遞,不受子孫組件的影響,適用于插槽,嵌套插槽;不適合兄弟通訊,父級組件無法主動通信 |
| $attrs / $listeners | 主要時解決了props傳遞數據不能跨層的缺點,但無法兄弟傳參 |
| $children / $parent | 方便直接,但 this.$children不可控性大,有一定風險。(盡量不用) |
| ref / refs | 渲染完成后才可使用,不是響應式的,時不時配合$nextTick |
| vuex | 處理復雜的組件通信的最佳方案,支持異步組件通信,缺點是流程相比稍微復雜 |
| EventBus | 簡單靈活,父子兄弟通信不受限制,通信方式不受框架影響,但維護困難,需要謹小慎微的命令規范,不利于組件化開發 |
| localStorage / sessionStorage | 常用于存儲用戶信息,系統設置,token等 |
-
父子組件通信: props / $emit; .sync/update;provide/inject; $parent / $children; ref/refs; $attrs/$listeners
-
非父子組件/兄弟組件通信: EventBus ; Vuex;localStorage/sessionStorage
總結
以上是生活随笔為你收集整理的vue组件通信大总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle监听服务无法启动不了,关于O
- 下一篇: 进行判断使用class_记一次使用 Ar