兩種語法糖,搞定Vue元件Prop的雙向繫結

炸雞啤酒不可負發表於2020-10-16
無論是vue還是react,在父子元件通訊的時候,子元件都禁止直接修改父級傳過來的prop,父元件總需要在子元件身上監聽一個事件,然後由子元件去觸發它,好讓父元件來接收到payload去改變state。能不能直接在子元件裡修改prop,然後父元件中的state也隨之改變呢? 其實本質上是不行的,但幸運的是,vue為我們準備了兩個語法糖做到了這一點,讓我們減少了一點寫大量模板程式碼的痛苦。它們就是自定義元件上的 v-model指令以及 .sync修飾符。
假如我們有如下的一個父元件,想為子元件傳遞一個名為val的prop,並且期待有雙向繫結的效果:
<template>
  <child-component :val="val"  data-tomark-pass />
</template>
<script>
export default {
  data() {
    return {
      val: 100
    }
  }
}
</script>
而子元件負責接收val,並且每click一次button,則讓val+2:
<template>
  <div>
    <div>{{val}}</div>
    <button @click="handleClick">click</button>
  </div>
</template>

透過v-model

一個元件上的 v-model 預設會利用名為  value 的 prop 和名為  input 的事件,但是像單選框、核取方塊等型別的輸入控制元件可能會將  value attribute 用於不同的目的。利用 model 選項可以用來避免這樣的衝突。換句話說,你可以將 v-model的prop以任意名稱來接收,不一定要使用 value, 事件名稱也可以是任意的,不一定非要寫成 input。如下例:
父元件透過v-model傳遞val值:
<template>
  <child-component v-model="val"  data-tomark-pass />
</template>
而子元件內透過model選項去繫結這個prop:
export default {
  model: {
    prop: 'anyKey',  // 不一定非要是value
    event: 'anyEventName'  // 不一定非要是input
  },
  props: {
    anyKey: {
      type: Number
    }
  },
  methods: {
    handleClick() {
      this.$emit('anyEventName', this.anyKey+2)
    }
  }
}
父元件裡的  val 的值將會傳入這個名為  anyKey 的 prop。同時當子元件 <child-component> 觸發一個  anyEventName 事件並附帶一個新的值的時候,父元件 val 的 state 將會被更新。

透過.sync修飾符

父元件透過.sync修飾符傳遞val值:
<template>
  <child-component :val.sync="val"  data-tomark-pass />
</template>
子元件內接收更簡單,因為vue內部幫我們繫結了 update:myPropName這樣一個事件:
export default {
  props: {
    val: {
      type: Number
    }
  },
  methods: {
    handleClick() {
      this.$emit('update:val', this.val+2)
    }
  }
}
.sync修飾符寫起來更簡便一些,雙向繫結爽歪歪。不過有一點要注意,像 v-bind.sync=”{ title: doc.title }”這種繫結字面量物件,修飾符是無法正常工作的。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69983799/viewspace-2727446/,如需轉載,請註明出處,否則將追究法律責任。

相關文章