vue父子關係元件間的雙向資料繫結

mushang發表於2018-04-20

vue元件間通訊(1-父子)

props

父傳子時,我們通常使用自定義屬性,props接收。

但是大家都知道,這種資料傳遞是單向的,只能父傳子,而子元件也不能直接去操作這個資料;

# Prop 是單向繫結的:當父元件的屬性變化時,將傳導給子元件,
但是反過來不會。這是為了防止子元件無意間修改了父元件的狀態,來避免應用的資料流變得難以理解。

# 另外,每次父元件更新時,子元件的所有 prop,都會更新為最新值。這意味著你不應該在子元件內部改變 prop。
複製程式碼

在兩種情況下,我們很容易忍不住想去修改 prop 中資料:

#1 Prop 作為初始值傳入後,子元件想把它當作區域性資料來用;
#2 Prop 作為原始資料傳入,由子元件處理成其它資料輸出。
複製程式碼

對這兩種情況,正確的應對方式是:

定義一個區域性變數,並用 prop 的值初始化它:

props: ['initialCounter'],
data: function () {
  return { counter: this.initialCounter }
}
複製程式碼

定義一個計算屬性,處理 prop 的值並返回:

props: ['size'],
computed: {
  normalizedSize: function () {
    return this.size.trim().toLowerCase()
  }
}
複製程式碼

$emit

子傳父時,我們通常使用自定義方法,子元件呼叫$emit( event, […args] )執行函式,並傳遞引數,這樣就實現了子傳父


父元件
複製程式碼
<pageHeader v-on:isBack="fun" title="個人資訊"></pageHeader>
複製程式碼

子元件中
複製程式碼
<div @click="clickDiv">點我觸發事件</div>


----------
methods: {
clickDiv () {
    this.$emit('update:isBack', '引數')
    }
}

複製程式碼

.sync 修飾符

但是這樣如果只是想實現傳遞引數,那就有點麻煩了,因為我們還需要在父元件定義函式去接收,我們希望實現一種雙向資料繫結;
    #在我們修改了子元件的資料時能夠同步更新父元件,於是我就找到了這個方法
    # Vue 1.x 中的 .sync 修飾符實現了對一個 prop 進行“雙向繫結”,當一個子元件改變了一個帶 .sync 的 prop 的值時,這個變化也會同步到父元件中所繫結的值。這很方便,但也會導致問題。(官網給出了較為詳細的說明,因為它破壞了單向資料流,debug 複雜結構的應用時會帶來很高的維護成本。
    # 在 2.0 中移除 .sync ;但是在 2.0 釋出之後的實際應用中,我們發現 .sync 還是有其適用之處,比如在開發可複用的元件庫時。我們需要做的只是讓子元件改變父元件狀態的程式碼更容易被區分。
    # 從 2.3.0 起我們重新引入了 .sync 修飾符)
下面的程式碼
複製程式碼
<pageHeader :isBack.sync="parameter" title="個人資訊"</pageHeader>` 
複製程式碼
會被擴充套件為
複製程式碼
<pageHeader :isBack.sync="parameter" @update:isBack="val => parameter = val title="個人資訊"</pageHeader>
複製程式碼

子元件中
複製程式碼
<div @click="clickDiv">點我觸發事件</div>
複製程式碼
methods: {
clickDiv () {
    this.$emit('update:isBack', '引數')
    }
}

複製程式碼

當使用一個物件一次性設定多個屬性的時候,這個 .sync 修飾符也可以和 v-bind 一起使用:

<comp v-bind.sync="{ foo: 1, bar: 2 }"></comp>
複製程式碼

這個例子會為 foo 和 bar 同時新增用於更新的 v-on 監聽器。


js資料儲存原理

以上為比較正統的寫法,也是比較推薦的,有的時候我們想要更加巧妙地方法實現,那麼我們可以利用js中物件和陣列是引用型別,指向同一個記憶體空間的原理。

如果 prop 是一個物件或陣列,在子元件內部改變它會影響父元件的狀態。
即,將需要傳遞的引數放到一個物件或者陣列裡傳遞,在子元件中修改物件的屬性,就會聯動觸發父元件的檢視更新了。
# 因為,他們操作的是同一個記憶體地址引用的物件複製程式碼

相關文章