Vue 單向數據流 之 對象

  1. 父組件將 數據(Object) 傳遞到子組件
  2. 子組件直接使用這個對象,並修改這個對象,會影響到父組件中的對象;
  3. 子組件通過data,將父組件傳遞過來的對象轉換成本地數據,修改對象依然會影響到父級數據,因爲對象是引用數據類型,如下圖所示;
props: ['obj'],
data(){
	return {
		iObj: this.obj
	}
}

在這裏插入圖片描述

所以就需要讓本地對象跟父級對象徹底斷絕聯繫;
有以下兩種方法:
1. 深拷貝

props: ['obj'],
data(){
	return {
		iObj: JSON.parse(JSON.stringify(this.obj))
	}
}

2. 擴展運算符 ...

props: ['obj'],
data(){
	return {
		iObj: {
			...this.obj
		}
	}
}

子組件修改數據之後,父組件的數據也需要隨之修改,該怎麼處理呢?
那就是監聽子組件的數據變化,通過 $emit 通知父組件更新數據;
要知道,普通的監聽對於對象來說是無效的,所以在子組件中 監聽對象數據的變化 方法如下:

// 需要注意的是, 如下傳遞給父組件的對象也進行了一次轉換(...this.iObj),徹底避免掉引用關係
watch: {
    iObj: {
        handler(newVal){
            this.$emit('upDate', {...this.iObj})
        },
        deep: true
    }
},

所以一個對象,從傳入子組件,到子組件更新後將新數據傳遞到父組件的過程如下:

Vue.component('test', {
    props: ['obj'],
    // 通過擴展運算符,將父組件傳遞過來的對象徹底轉換成本地數據
    data() {
        return {
            iObj: {
                ...this.obj
            }
        }
    },
    // 監聽本地對象的變化,更新到父組件
    watch: {
        iObj: {
            handler(newVal){
                this.$emit('upDate', {...this.iObj})
            },
            deep: true
        }
    },
    template: `
    <div>
        <p>子組件:{{iObj}}</p>
        <input type="text" v-model="iObj.name" />
    </div>
    `
});
new Vue({
    el: "#app",
    data() {
        return {
            obj: {name: "任重道遠"}
        }
    },
    methods: {
        update(newVal){
            this.obj = newVal;
        }
    },
    template: `
    <div>
        <h2>父組件: {{obj}}</h2>
        <test :obj="obj" @upDate="update"/>
    </div>
    `
})
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章