vue的單項數(shù)據(jù)流和sync實現(xiàn)父子組件雙向綁定

vue的單項數(shù)據(jù)流

  • 所有的 prop 都使得其父子 prop 之間形成了一個單向下行綁定:父級 prop 的更新會向下流動到子組件中,但是反過來則不行。這樣會防止從子組件意外改變父級組件的狀態(tài),從而導(dǎo)致你的應(yīng)用的數(shù)據(jù)流向難以理解。

  • 額外的,每次父級組件發(fā)生更新時,子組件中所有的 prop 都將會刷新為最新的值。這意味著你不應(yīng)該在一個子組件內(nèi)部改變 prop。如果你這樣做了,Vue 會在瀏覽器的控制臺中發(fā)出警告。

  • 如果是一個對象或者數(shù)組,那么當(dāng)子組件改變時,也會影響到父組件;是由于是同一個空間地址的原因;(破壞了單項數(shù)據(jù)流)

上個例子說明一下
<div id="app">
    <div @click="fn">{{msg}}</div>
    <son :m="msg"></son>
</div>
let vm = new Vue({
        el:"#app",
        data: {
            msg:"hello"
        },
        methods:{
            fn(){
                this.msg = "hahaha"
            }
        },
        components:{
            son:{
                data(){
                     return {}
                },
                props:["m"],
                // props : 會把這個屬性放到當(dāng)前的組件的實例的屬性上;
                // 通過props傳遞過來的數(shù)據(jù)也具有響應(yīng)式;但是不能再次傳遞父組件;
                template:"<div @click='fn'>{{m}}</div>",
                methods:{
                    fn(){
                        // 在組件的函數(shù)或者事件中,那么函數(shù)中的this指向了當(dāng)前組件的實例;
                        console.log(this);
                        console.log(this.m);
                        this.m = "world";
                    }
                }
            }
        }
    });

以上代碼雖然能夠?qū)崿F(xiàn)子組件的數(shù)據(jù)更改父組件的數(shù)據(jù),但是這樣做控制臺會發(fā)出警告:


image.png

并且做出了正確的提示
使用data屬性或者computed屬性接收一下這個prop的值,然后在做響應(yīng)的改變,并且不能和prop的值重名,像這樣:

props: ['m'],
data: function () {
  return {
    counter: this.m
  }
}

或者這樣

props: ['m'],
computed: {
  mc: function () {
    return this.m.trim().toLowerCase()//這里做對于prop的值的一些處理
  }
}

最后的效果是,子組件中能夠隨意使用prop的值,又不會改變父級的數(shù)據(jù),應(yīng)為用data或者computed做了一層攔截

let vm = new Vue({
        el:"#app",
        data: {
            msg:"hello"
        },
        methods:{
            fn(){
                this.msg = "hahaha"
            }
        },
        components:{
            son:{
                data(){
                     return {con:this.m}
                },
                props:["m"],
                // props : 會把這個屬性放到當(dāng)前的組件的實例的屬性上;
                // 通過props傳遞過來的數(shù)據(jù)也具有響應(yīng)式;但是不能再次傳遞父組件;
                template:"<div @click='fn'>{{m}}<br>{{con}}</div>",
                methods:{
                    fn(){
                        // 在組件的函數(shù)或者事件中,那么函數(shù)中的this指向了當(dāng)前組件的實例;
                        console.log(this.m);
                        this.con = "world";
                        console.log(this.con)
                    }
                }
            }
        }
    });

sync修飾符實現(xiàn)父子組件數(shù)據(jù)的雙向綁定

  • 父組件的數(shù)據(jù)改變影響子組件數(shù)據(jù),子組件數(shù)據(jù)改變影響父組件數(shù)據(jù),本質(zhì)上父傳子數(shù)據(jù)用的props,子傳父數(shù)據(jù)用的是發(fā)布訂閱
上個例子:
<div id="app">
    {{money}}
    <!--綁定自定義事件的過程,就是訂閱的過程;-->
    <!--叫發(fā)布訂閱的語法糖:簡寫-->
    <!--<child  v-bind:m="money" v-on:update:m="money=$event"></child>-->
    <child :m.sync="money"></child>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
    let vm = new Vue({
        el: '#app',
        data: {
            money : 400
        },
        components:{
            child:{
                data(){
                    return {}
                },
                props:["m"],
                template:"<div>{{m}}<button @click='fn'>改變數(shù)據(jù)</button></div>",
                methods:{
                    fn(){
                        // 希望在fn執(zhí)行時,觸發(fā)父組件身上的change方法;
                        this.$emit("update:m",888)
                    }
                }
            }
        }

    });
</script>
  • 子組件中不操作props屬性,而是直接$emit事件和數(shù)據(jù),直接改變父組件的數(shù)據(jù)
<child  v-bind:m="money" v-on:update:m="money=$event"></child>
$event是子組件$emit 發(fā)布的數(shù)據(jù)888
<child :m.sync="money"></child>
.sync只是update的簡寫的一個語法糖
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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