因為業務需要,最近不寫 iOS,也不寫 Ruby 了,開始寫錢端。然後…做為一個錢端 P0,表示用了 Electron 和餓了麼大錢端的 Element 庫之後,好像一直都很順利,直到…我碰到了元件間值同步的問題?。
需求是這樣的,我需要點選一個按鈕,然後開啟一個對話方塊用來新建一些東西。 對話方塊的話我當然是用 el-dialog
來做啊,Element!So easy!!!el-dialog
有個叫 :visible.sync
的屬性,用來控制它的顯示和隱藏。
如果我不封裝這個對話方塊,直接放在當前頁面,像下面這樣設定就 OK 了:
<template>
<el-dialog :visible.sync="visible"></el-dialog>
</template>
<script>
export default {
data () {
return {
visible: false
}
}
}
</script>
複製程式碼
這樣一來我只需要設定 visible
的值就可以控制 el-dialog
節點 的顯示和隱藏了:
<el-button @click="visible = true"></el-button>
複製程式碼
不過本人是個封裝控?,el-dialog
裡面還有一堆東西呢,直接放在這不能忍,所以我很乾脆的把這個 el-dialog
和它的資料放到另外一個元件(PS:子元件)去了,然後,問題就來了:我的按鈕還在當前元件裡(PS:父元件),上面這行程式碼我控制不了這個 visible
屬性了。What the Fuck!!!我需要學習,然後各種查,問,試,期間曲折的過程我就不說了,直接放最終我個人覺得比較能接受的版本吧:
首先我們先定義子元件:
<template>
<el-dialog :visible.sync="visible"></el-dialog>
</template>
<script>
export default {
props: {
pvisible: Boolean
},
computed: {
visible: {
// getter
get: function () {
return this.pvisible
},
// setter
set: function (newValue) {
this.$emit('update:pvisible', newValue)
}
}
}
}
</script>
複製程式碼
這裡有幾個關鍵點:
- 父元件會有一個值和子元件的
pvisible
繫結,然後通過props
傳遞過來,而且需要指定型別,不指定的話預設是字串型別。 - 需要一個
computed
的屬性visible
來控制el-dialog
的顯示和隱藏,為什麼是computed
?原因有兩個:-
get
方法可以直接獲取pvisible
的值並控制el-dialog
的顯示和隱藏。 -
要避免直接操作
props
裡面pvisible
的值,如果直接操作,就會報下面的 warning: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: "pvisible"
這是時候
set
方法就可以通過emit
方法修改父元件裡的那個值,然後因為父元件裡的那個值和子元件的pvisible
是繫結的,從而pvisible
也會發生變化,這樣就避免了上面的問題。
-
emit
方法第一個引數中的update:
是固定的,不能瞎寫,這個和 vue 2.3.x 以後的新增特性有關。另外pvisible
是父元件中那個值的名字。
然後是父元件:
<template>
<child-components v-bind:pvisible.sync="pvisible"></child-components>
</template>
<script>
import ChildComponents from './ChildComponents'
export default {
data () {
return {
pvisible: false
}
},
components: { ChildComponents }
}
</script>
複製程式碼
這裡同樣有幾個關鍵點:
- 需要一個
pvisible
屬性來繫結子元件裡props
中pvisible
。 v-bind:pvisible.sync="pvisible"
就是剛才說的 vue 2.3.x 以後的新特性,繫結屬性的同時,接收子元件emit
訊息更新。
現在我們就可以在父元件通過設定 pvisible
為 true
來顯示對話方塊,然後在子元件中通過設定 visible
為 false
來隱藏對話方塊了。而且他們的狀態只儲存在父元件的 pvisible
中,兩邊改變的也都是 pvisible
的值,這樣就達到了資料統一,並通過資料的改變驅動頁面變化的效果。
Emmm,這也是為什麼我的文章標題是偽雙向繫結了,因為其實改的值都是一個,繫結是單向的,不過因為一些語法糖,然後看起來像是雙向繫結了 pvisible
和 visible
這兩個值。
最後,我的理解很有可能是錯的,所以還請各位錢端大佬多多指正!!!感謝?