Vue組件傳遞數(shù)據(jù)與通信

對于使用Vue的新手來說,組件之間的數(shù)據(jù)傳遞是一個(gè)比較麻煩的問題,在開發(fā)中我自己也踩了不少坑,這篇文章簡單地做了一個(gè)總結(jié)。

首先,在 Vue 中,父子組件的關(guān)系可以總結(jié)為 props down, events up。父組件通過 props 向下傳遞數(shù)據(jù)給子組件,子組件通過 events 給父組件發(fā)送消息。如下圖:

目錄

  • 1. 父子組件之間的數(shù)據(jù)傳遞
    • 1.1 父組件向子組件傳遞數(shù)據(jù)
    • 1.2 子組件向父組件傳遞事件
  • 2. 非父子關(guān)系組件之間的數(shù)據(jù)傳遞

父子組件之間的數(shù)據(jù)傳遞

父組件向子組件傳遞數(shù)據(jù)

組件實(shí)例的作用域(scope)是孤立的,所以組件之間無法相互訪問到對方的數(shù)據(jù),所以這里我們需要在子組件中使用props選項(xiàng)去接受來自父組件傳遞進(jìn)來的動態(tài)數(shù)據(jù),并且在父組件的標(biāo)簽上綁定v-bind該數(shù)據(jù),這樣一來,我們就把父組件中的數(shù)據(jù)傳遞給了子組件中。

// 創(chuàng)建父組件
Vue.component("m-super", {
    data: ()=>{
        return {
            message: "Hello Super"
        }
    },
    template: `<div>
            <input placeholder='請輸入message的值' v-model='message'></input>
            <br/>
            <m-child :message='message'></m-child>
            </div>`
});

// 創(chuàng)建子組件,并需要把父組件的message的值傳遞給子組件
Vue.component("m-child", {
    props: ["message"],
    template: "<span>子組件顯示:{{ message }}</span>"
})

props數(shù)據(jù)是單向傳遞

props是單向綁定的:當(dāng)父組件的屬性變化時(shí),將傳導(dǎo)給子組件,但是不會反過來。

這是為了防止子組件無意修改了父組件的狀態(tài)——這會讓應(yīng)用的數(shù)據(jù)流難以理解。

每次父組件更新時(shí),子組件的所有 prop 都會更新為最新值。這意味著你不應(yīng)該在子組件內(nèi)部改變 prop。如果你這么做了,Vue 會在控制臺報(bào)錯(cuò)。如下:

[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "message"

子組件向父組件傳遞事件

因?yàn)?code>prop是單向數(shù)據(jù)流的,所以prop接受的數(shù)據(jù)是無法雙向綁定的,那么如何改變父組件的數(shù)據(jù)呢——使用vue自定義事件。

  • 子組件中我們可以通過$emit(eventName)來觸發(fā)事件
  • 父組件中我們可以通過$on(eventName)來監(jiān)聽事件

下面給子組件添加了一個(gè)重置按鈕,一按就可以將父組件的值改為Hello Child。代碼如下:

// 創(chuàng)建父組件
Vue.component("m-super", {
    data: ()=>{
        return {
            message: "Hello Super"
        }
    },
    template: `<div>
            <input placeholder='請輸入message的值' v-model='message'></input>
            <br/>
            <m-child :message='message' v-on:reset="reset"></m-child>
            </div>`,
    methods:{
        reset:function(e){
            this.message = e
        }
    }
});

// 創(chuàng)建子組件,并需要把父組件的message的值傳遞給子組件
Vue.component("m-child", {
    props: ["message"],
    template: "<div><span>子組件顯示:{{ message }}</span><br/><button v-on:click='reset()'>重置</button></div>",
    methods: {
        reset:function(){
            this.$emit("reset", "Hello child")
        }
    }
})

這樣一來,我們便實(shí)現(xiàn)了父子組件數(shù)據(jù)的雙向綁定。

非父子組件之間的數(shù)據(jù)傳遞

對于非父子組件通信情況,在簡單的場景下,可以使用一個(gè)空的Vue實(shí)例作為中央事件總線:

var bus = new Vue()
// 觸發(fā)組件 A 中的事件
bus.$emit('id-selected', 1)
// 在組件 B 創(chuàng)建的鉤子中監(jiān)聽事件
bus.$on('id-selected', function (id) {
// ...
})

如果非父子組件通信比較復(fù)雜時(shí),我們可以通過Vuex來解決。


歡迎關(guān)注我的微信公眾號

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 這篇筆記主要包含 Vue 2 不同于 Vue 1 或者特有的內(nèi)容,還有我對于 Vue 1.0 印象不深的內(nèi)容。關(guān)于...
    云之外閱讀 5,186評論 0 29
  • 序 今年大前端的概念一而再再而三的被提及,那么大前端時(shí)代究竟是什么呢?大前端這個(gè)詞最早是因?yàn)樵诎⒗飪?nèi)部有很多前端開...
    一縷殤流化隱半邊冰霜閱讀 11,387評論 19 92
  • 此文基于官方文檔,里面部分例子有改動,加上了一些自己的理解 什么是組件? 組件(Component)是 Vue.j...
    陸志均閱讀 3,955評論 5 14
  • Vue 實(shí)例 屬性和方法 每個(gè) Vue 實(shí)例都會代理其 data 對象里所有的屬性:var data = { a:...
    云之外閱讀 2,389評論 0 6
  • 讀圖書館里借閱的《安娜卡列尼娜》,下卷第七章,安娜的小女兒安妮生病了,但安娜并不關(guān)心女兒的病情而是以此為理由,添油...
    西安客閱讀 1,051評論 0 9

友情鏈接更多精彩內(nèi)容