Vue 3.0 v-model

2021-11-03 15:37 更新

#概覽

就變化內(nèi)容而言,此部分屬于高階內(nèi)容:

  • 非兼容:用于自定義組件時(shí),v-modelprop 和事件默認(rèn)名稱已更改:
    • prop:value -> modelValue
    • event:input -> update:modelValue;

  • 非兼容v-bind.sync 修飾符和組件的 model 選項(xiàng)已移除,可用 v-model 作為代替;

  • 新增:現(xiàn)在可以在同一個(gè)組件上使用多個(gè) v-model 進(jìn)行雙向綁定;

  • 新增:現(xiàn)在可以自定義 v-model 修飾符。

更多信息,請(qǐng)見(jiàn)下文。

#介紹

在 Vue 2.0 發(fā)布后,開(kāi)發(fā)者使用 v-model 指令必須使用為 value 的 prop。如果開(kāi)發(fā)者出于不同的目的需要使用其他的 prop,他們就不得不使用 v-bind.sync。此外,由于v-modelvalue 之間的這種硬編碼關(guān)系的原因,產(chǎn)生了如何處理原生元素和自定義元素的問(wèn)題。

在 Vue 2.2 中,我們引入了 model 組件選項(xiàng),允許組件自定義用于 v-model 的 prop 和事件。但是,這仍然只允許在組件上使用一個(gè) model

在 Vue 3 中,雙向數(shù)據(jù)綁定的 API 已經(jīng)標(biāo)準(zhǔn)化,減少了開(kāi)發(fā)者在使用 v-model 指令時(shí)的混淆并且在使用 v-model 指令時(shí)可以更加靈活。

#2.x 語(yǔ)法

在 2.x 中,在組件上使用 v-model 相當(dāng)于綁定 value prop 和 input 事件:

<ChildComponent v-model="pageTitle" />


<!-- 簡(jiǎn)寫: -->


<ChildComponent :value="pageTitle" @input="pageTitle = $event" />

如果要將屬性或事件名稱更改為其他名稱,則需要在 ChildComponent 組件中添加 model 選項(xiàng):

<!-- ParentComponent.vue -->


<ChildComponent v-model="pageTitle" />

// ChildComponent.vue


export default {
  model: {
    prop: 'title',
    event: 'change'
  },
  props: {
    // 這將允許 `value` 屬性用于其他用途
    value: String,
    // 使用 `title` 代替 `value` 作為 model 的 prop
    title: {
      type: String,
      default: 'Default title'
    }
  }
}

所以,在這個(gè)例子中 v-model 的簡(jiǎn)寫如下:

<ChildComponent :title="pageTitle" @change="pageTitle = $event" />

#使用 v-bind.sync

在某些情況下,我們可能需要對(duì)某一個(gè) prop 進(jìn)行“雙向綁定”(除了前面用 v-model 綁定 prop 的情況)。為此,我們建議使用 update:myPropName 拋出事件。例如,對(duì)于在上一個(gè)示例中帶有 title prop 的 ChildComponent,我們可以通過(guò)下面的方式將分配新 value 的意圖傳達(dá)給父級(jí):

this.$emit('update:title', newValue)

如果需要的話,父級(jí)可以監(jiān)聽(tīng)該事件并更新本地 data property。例如:

<ChildComponent :title="pageTitle" @update:title="pageTitle = $event" />

為了方便起見(jiàn),我們可以使用 .sync 修飾符來(lái)縮寫,如下所示:

<ChildComponent :title.sync="pageTitle" />

#3.x 語(yǔ)法

在 3.x 中,自定義組件上的 v-model 相當(dāng)于傳遞了 modelValue prop 并接收拋出的 update:modelValue 事件:

<ChildComponent v-model="pageTitle" />


<!-- 簡(jiǎn)寫: -->


<ChildComponent
  :modelValue="pageTitle"
  @update:modelValue="pageTitle = $event"
/>

#v-model 參數(shù)

若需要更改 model 名稱,而不是更改組件內(nèi)的 model 選項(xiàng),那么現(xiàn)在我們可以將一個(gè) argument 傳遞給 model

<ChildComponent v-model:title="pageTitle" />


<!-- 簡(jiǎn)寫: -->


<ChildComponent :title="pageTitle" @update:title="pageTitle = $event" />

v-bind anatomy

這也可以作為 .sync 修飾符的替代,而且允許我們?cè)谧远x組件上使用多個(gè) v-model。

<ChildComponent v-model:title="pageTitle" v-model:content="pageContent" />


<!-- 簡(jiǎn)寫: -->


<ChildComponent
  :title="pageTitle"
  @update:title="pageTitle = $event"
  :content="pageContent"
  @update:content="pageContent = $event"
/>

#v-model 修飾符

除了像 .trim 這樣的 2.x 硬編碼的 v-model 修飾符外,現(xiàn)在 3.x 還支持自定義修飾符:

<ChildComponent v-model.capitalize="pageTitle" />

我們可以在 Custom Events 部分中了解有關(guān)自定義 v-model 修飾符的更多信息。

#遷移策略

我們推薦:

  • 檢查你的代碼庫(kù)中所有使用 .sync 的部分并將其替換為 v-model

  <ChildComponent :title.sync="pageTitle" />

  
  <!-- 替換為 -->

  
  <ChildComponent v-model:title="pageTitle" />

  • 對(duì)于所有不帶參數(shù)的 v-model,請(qǐng)確保分別將 prop 和 event 命名更改為 modelValueupdate:modelValue

  <ChildComponent v-model="pageTitle" />

  // ChildComponent.vue

  
  export default {
    props: {
      modelValue: String // 以前是`value:String`
    },
    methods: {
      changePageTitle(title) {
        this.$emit('update:modelValue', title) // 以前是 `this.$emit('input', title)`
      }
    }
  }

#下一步

更多新的 v-model 語(yǔ)法相關(guān)信息,請(qǐng)參考:

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)