Vue父子組件之間的通信方式

在Vue2.X中,父子組件之間有兩點(diǎn)非常重要的通信原則:

  • 父子組件是單向數(shù)據(jù)流,父組件的狀態(tài)更新,子組件中prop的狀態(tài)也會(huì)更新,但是子組件的狀態(tài)變化不會(huì)影響父組件。在子組件中修改prop的狀態(tài),會(huì)在console中報(bào)錯(cuò)。關(guān)于單向數(shù)據(jù)流,Vue文檔中是這樣來(lái)描述原因的:

    這是為了防止子組件無(wú)意間修改了父組件的狀態(tài),來(lái)避免應(yīng)用的數(shù)據(jù)流變得難以理解。

    有一點(diǎn)應(yīng)該注意,如果父組件傳遞給子組件的狀態(tài)是對(duì)象或者數(shù)組,因?yàn)閮烧呤前匆脗髦?,所以在子組件中是可以改變對(duì)象和數(shù)組中的值的,同時(shí)也會(huì)影響到父組件的狀態(tài)。

  • 每次父組件狀態(tài)更新時(shí),父組件的所有雙向綁定的model都會(huì)進(jìn)行更新;同時(shí),子組件的所有 prop 也會(huì)進(jìn)行更新。這里要注意,父組件中更新的狀態(tài),必須在父組件中進(jìn)行了雙向綁定,或者傳遞到了子組件,才會(huì)觸發(fā)父組件的其他狀態(tài)的更新。

如果希望在子組件中改變父組件的狀態(tài),有兩種方式:

  • 其一是通過(guò)事件派發(fā),父組件響應(yīng)子組件派發(fā)的事件,由父組件自己改變自己的狀態(tài)
  • 其二是父組件向子組件傳遞數(shù)組或者對(duì)象,在子組件中改變數(shù)組或者對(duì)象的狀態(tài)

因?yàn)閂ue的雙向數(shù)據(jù)綁定是基于Object.defineProperty()來(lái)劫持屬性的settergetter方法,由于js的限制,如果某一個(gè)組件的狀態(tài)是一個(gè)數(shù)組,對(duì)數(shù)組的修改無(wú)法通過(guò)Object.defineProperty()劫持到,所以無(wú)法把狀態(tài)的更新反饋到視圖上。舉一個(gè)例子,下面是一個(gè)Vue單文件組件,當(dāng)我點(diǎn)擊按鈕的時(shí)候,視圖無(wú)法更新。

<template>
    <div id="header-ctn">
        hello {{msg[0]}}
        <button @click="change">點(diǎn)我改變組件狀態(tài)</button>
    </div>

</template>
<script>
    export default {
        data () {
            return {
                msg: ['yanbin', 'bluestrings']
            }
        },
        mounted () {
        },
        methods: {
            change () {
               this.msg[0] = '閆斌';//應(yīng)該寫成 this.$set(this.msg, 0, "閆斌");
            }
        }
    }
</script>

所以Vue提供了操作數(shù)組的方法來(lái)解決這個(gè)問(wèn)題:

Vue.set(array, pos, newVal);

但是在很多實(shí)際的case中,即使沒(méi)有用Vue.set這個(gè)方法來(lái)操作數(shù)組,我們發(fā)現(xiàn)數(shù)組的變化依然反饋到了視圖上,這是什么原因呢?這里就要提到剛才說(shuō)到的一點(diǎn),如果當(dāng)前組件的某一個(gè)狀態(tài)發(fā)生更新,Vue會(huì)強(qiáng)制自動(dòng)刷新其他綁定的狀態(tài),也就是說(shuō)組件狀態(tài)反饋到視圖上的這個(gè)操作是Vue自動(dòng)執(zhí)行的,而不再是通過(guò)Object.defineProperty()來(lái)劫持的。拿剛才的例子修改一下:

<template>
    <div id="header-ctn">
        hello {{msg[0]}}<br/>
        今天{{day}}
        <button @click="change">點(diǎn)我改變組件狀態(tài)</button>
    </div>

</template>
<script>
    export default {
        data () {
            return {
                msg: ['yanbin', 'bluestrings'],
                day: '星期天'
            }
        },
        mounted () {
        },
        methods: {
            change () {
               this.msg[0] = '閆斌';
               this.day = '星期一';
            }
        }
    }
</script>
<style lang="less">

</style>

因?yàn)樾薷牧私M件的狀態(tài)day,所以Vue將msg這個(gè)數(shù)組的更新也反饋到了視圖上。

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

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

  • 這篇筆記主要包含 Vue 2 不同于 Vue 1 或者特有的內(nèi)容,還有我對(duì)于 Vue 1.0 印象不深的內(nèi)容。關(guān)于...
    云之外閱讀 5,178評(píng)論 0 29
  • 1.安裝 可以簡(jiǎn)單地在頁(yè)面引入Vue.js作為獨(dú)立版本,Vue即被注冊(cè)為全局變量,可以在頁(yè)面使用了。 如果希望搭建...
    Awey閱讀 11,300評(píng)論 4 129
  • Vue 實(shí)例 屬性和方法 每個(gè) Vue 實(shí)例都會(huì)代理其 data 對(duì)象里所有的屬性:var data = { a:...
    云之外閱讀 2,373評(píng)論 0 6
  • 聽(tīng)到《野薔薇》這首曲的時(shí)候,是最艱難的一短時(shí)間。 離開熟悉的環(huán)境,到陌生的地方,一片空白,從頭學(xué)起。深夜頂著皎潔的...
    元寶小宇宙閱讀 727評(píng)論 0 0
  • 題目將一個(gè)正整數(shù)分解質(zhì)因數(shù)。例如:輸入90,打印出90=233*5. 程序分析 對(duì)n進(jìn)行分解質(zhì)因數(shù),應(yīng)先找到一個(gè)最...
    NoFacePeace閱讀 824評(píng)論 0 0

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