在專案中開始使用vue2來構建專案了,跟 vue1 很大的一處不同在於2 取消了props 的雙向繫結,改成只能從父級傳到子級的單向資料流,初衷當然是好的,為了避免雙向繫結在專案中容易造成的資料混亂。
解決方案一
然後開始參考網上和github上的方案等等,發現很多解決方案是這樣的
-
用data物件中建立一個props屬性的副本
-
watch props屬性 賦予data副本 來同步元件外對props的修改
-
watch data副本,emit一個函式 通知到元件外
這裡以最常見的 modal為例子:
modal挺合適雙向繫結的,外部可以控制元件的 顯示或者隱藏,元件內部的關閉可以控制 visible屬性隱藏,同時visible 屬性同步傳輸到外部
///modal.vue 元件
<template>
<div class="modal" v-show="visible">
<div class="close" @click="cancel">X</div>
</div>
</template>
<script>
export default {
name:`modal`,
props: {
value: {
type: Boolean,
default:false
}
},
data () {
return {
visible:false
}
},
watch:{
value(val) {
console.log(val);
this.visible = val;
},
visible(val) {
this.$emit("visible-change",val);
}
},
methods:{
cancel(){
this.visible = false;
}
},
mounted() {
if (this.value) {
this.visible = true;
}
}
}
</script>
///呼叫modal元件
<modal :value="isShow" @visible-change="modalVisibleChange"></modal>
export default {
name: `app`,
data () {
return {
isShow:true,
}
},
methods:{
modalVisibleChange(val){
this.isShow = val;
}
}
}
這樣就解決了 元件props 雙向繫結的問題。 但是這樣有一個不是太美觀的現象就是 在父級呼叫 modal元件的時候,還需要寫一個 modalVisibleChange 的methods. 總是顯得這部分程式碼是多餘的。 特別是寫一個讓別人用的公共元件,這樣呼叫太麻煩了。
能不能不寫method來實現props的雙向繫結呢,答案是可以的。
優美解決方案
那就是利用 v-model, 然後使用value來儲存v-model的值,進行雙向繫結
改成如下程式碼:
<template>
<div class="modal" :value="value" v-show="visible">
<div class="close" @click="cancel">X</div>
</div>
</template>
<script>
export default {
props: {
value: {
type: Boolean,
default:false
}
},
data () {
return {
visible:false
}
},
watch:{
value(val) {
console.log(val);
this.visible = val;
},
visible(val) {
this.$emit(`input`, val);
}
},
methods:{
cancel(){
this.visible = false;
}
},
mounted() {
if (this.value) {
this.visible = true;
}
}
}
</script>
///呼叫modal元件
<modal v-model="isShow"></modal>
export default {
name: `app`,
data () {
return {
isShow:false
}
}
}
</script>
這樣呼叫元件的程式碼是不是很簡潔,其他人員要呼叫的話,會很輕鬆,只要設定 isShow 就可以控制 modal 元件的顯示或者隱藏,同時 如果是modal 元件內部關閉按鈕關閉的,狀態也會傳到 isShow