Vue父子组件通信小总结
感覺Vue中父子傳參的方式,實(shí)在是太多了,于是做一個(gè)小總結(jié),只是總結(jié)我所知道的。 歡迎吐槽
1.父?jìng)髯?/h3>
基本就用一個(gè)方式,props
父親通過在 標(biāo)簽 中寫入需要傳入的數(shù)據(jù)。
<!--father.vue--> <template><div>我是爸爸,下面是兒子<son title='兒子' :selected='selected'></son></div> </template> 復(fù)制代碼兒子在 實(shí)例中的 props 選項(xiàng)中獲取
//son.vue export default {name:'son',props:{selected:{type:Boolean},title:{type:String}} } 復(fù)制代碼2.子傳父
# update:my-prop-name 模式
Vue 是單項(xiàng)數(shù)據(jù)流,所以不允許 兒子 直接修改父親的數(shù)據(jù),也不允許兒子直接修改自己的props。
假設(shè)一個(gè)情況,點(diǎn)擊兒子,兒子需要改變 selected 的狀態(tài)。
兒子方面
觸發(fā)點(diǎn)擊事件后, 讓兒子觸發(fā)一個(gè) update 事件,把新的 selected 傳出去
<!--son.vue--> <template><div class="son" @click="onClick">title:{{title}} selected:{{selected}}</div> </template> <script> export default {name: "son",props: {selected: {type: Boolean},title: {type: String}},methods: {onClick() {this.$emit("update:selected", !this.selected); //關(guān)鍵點(diǎn)}} }; </script><style> .son {border: 1px solid red; } </style> 復(fù)制代碼父親方面
在標(biāo)簽中監(jiān)聽 update事件,并將傳過來的 $event付給 selected,這樣就完成了一次傳參。
<!--father.vue--> <template><div>我是爸爸,下面是兒子<son title='兒子' :selected='selected' @update:selected='selected=$event'></son> <!--關(guān)鍵點(diǎn)--></div> </template><script> import Son from "./son"; export default {name: "father",components: {Son},data() {return {selected: true};} }; </script> 復(fù)制代碼簡(jiǎn)單方式
.sync 修飾符
<!--father.vue--> <template><div>我是爸爸,下面是兒子<son title='兒子' :selected.sync='selected'></son> <!--關(guān)鍵點(diǎn)--></div> </template> 復(fù)制代碼# $parents API
兒子方面
從 this.$parent中可以獲取到 父組件 的 data 數(shù)據(jù) ,直接進(jìn)行修改,是不是很刺激。
methods: {onClick() {this.$parent.selected = !this.$parent.selected;}} 復(fù)制代碼雖然刺激,但是,我建議調(diào)用父組件的函數(shù),來切換狀態(tài)。
父親方面
//father.vue export default {name: "father",components: {Son},data() {return {selected: true};},methods: {changeSelected() {this.selected = !this.selected;}} }; 復(fù)制代碼兒子方面
//son.vue methods: {onClick() {this.$parent.changeSelected();}} 復(fù)制代碼# EventBus
如果只是一個(gè)父親,一個(gè)兒子上面的方法非常的簡(jiǎn)單實(shí)用,但是如果是祖孫三代傳參呢?上面的方法就很麻煩了。
具體怎么麻煩,可以看一下我的這篇文章,用原始的方法造 tabs輪子:zhuanlan.zhihu.com/p/39601572
廢話不多說,開始用 EventBus做一個(gè)簡(jiǎn)單的 tabs組件。
#app.vue
<template><div id="app"><tab selected='news'><tab-item name='news'>新聞</tab-item><tab-item name='car'>汽車</tab-item><tab-item name=‘code’>代碼</tab-item><tab-pane name='news'>新聞列表</tab-pane><tab-pane name='car'>汽車列表</tab-pane><tab-pane name=‘code’>代碼列表</tab-pane></tab></div> </template><script> import Tab from "./components/tabs.vue"; import TabItem from "./components/tab-item"; import TabPane from "./components/tab-pane";export default {name: "app",components: {Tab,TabItem,TabPane} }; </script> 復(fù)制代碼# tabs.vue
<template><div><slot></slot></div> </template><script> import TabItem from "./tab-item.vue"; import Vue from "vue"; //引入VUE export default {name: "tab",props: {selected: {type: [Number, String]}},data() {return {eventBus: new Vue() // 創(chuàng)建 eventBus};},provide() {return {eventBus: this.eventBus // 提供 eventBus};},mounted() {this.eventBus.$emit("update:selected", this.selected); //發(fā)布消息,告訴大家,現(xiàn)在的selected是啥} }; </script><style> </style> 復(fù)制代碼# tabs-item.vue
<template><div @click="onClick" :class="{active}"><slot/></div> </template><script> export default {name: "tab-item",props: {name: {type: [String, Number]}},inject: ["eventBus"], //注入 eventBusdata() {return {active: false};},created() {this.eventBus.$on("update:selected", newSelected => {this.active = this.name === newSelected;}); //接收消息,如果newselected 和我的 name 相同,那么我就被選中了},methods: {onClick() {this.eventBus.$emit("update:selected", this.name);//發(fā)布消息,如果點(diǎn)擊了我,我就告訴大家,我被選中了}} }; </script><style> .active {color: red; } </style> 復(fù)制代碼# tab-pane.vue
<template><div v-if="active" class="pane"><slot/></div> </template><script> export default {name: "tab-pane",props: {name: {type: [String, Number]}},data() {return {active: false};},inject: ["eventBus"],//注入 eventBuscreated() {this.eventBus.$on("update:selected", newSelected => {this.active = this.name === newSelected;});//接收消息,如果newselected 和我的 name 相同,那么我就被選中了} }; </script><style> .pane {color: red; } </style> 復(fù)制代碼# 靈活運(yùn)用 provide inject
//father.vue export default {name:'father',data(){return {someThing:'father'}},provide(){return {father:this}} } 復(fù)制代碼//son.vue export default {name:'son',inject:['father'],methods:{onClick(){this.father.someThing = 'son'}} } 復(fù)制代碼轉(zhuǎn)載于:https://juejin.im/post/5b95c9ed6fb9a05cde1d35bf
總結(jié)
以上是生活随笔為你收集整理的Vue父子组件通信小总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 当React Native 遇到了Goo
- 下一篇: IOT/智能设备日志解决方案(1):概述