Vue 中實現雙向綁定的 4 種方法

1. v-model 指令

<input v-model="text" />
複製代碼

上例不過是一個語法糖,展開來是:javascript

<input :value="text" @input="e => text = e.target.value" />
複製代碼

2. .sync 修飾符

<my-dialog :visible.sync="dialogVisible" />
複製代碼

這也是一個語法糖,剝開來是:html

<my-dialog :visible="dialogVisible" @update:visible="newVisible => dialogVisible = newVisible" />
複製代碼

my-dialog 組件在 visible 變化時 this.$emit('update:visible', newVisible) 便可。vue

3. model 屬性 (JSX/渲染函數中)

Vue 在 2.2.0 版本之後,容許自定義組件的 v-model,這就致使在 JSX / 渲染函數中實現 v-model 時得考慮組件的不一樣配置,不能一概如此(假使 my-dialog 組件的 model{ prop: 'visible', event: 'change' }):java

{
  render(h) {
    return h('my-dialog', {
      props: { value: this.dialogVisible },
      on: { input: newVisible => this.dialogVisible = newVisible }
    })
  }
}
複製代碼

而應如此:git

{
  render(h) {
    return h('my-dialog', {
      props: { visible: this.dialogVisible },
      on: { change: newVisible => this.dialogVisible = newVisible }
    })
  }
}
複製代碼

然而,利用 model 屬性,徹底能夠作到不用管它 propevent 的目的:github

{
  render(h) {
    return h('my-dialog', {
      model: {
        value: this.dialogVisible,
        callback: newVisible => this.dialogVisible = newVisible
      }
    })
  }
}
複製代碼

JSX 中這樣使用:函數

{
  render() {
    return (
      <my-dialog {...{ model: { value: this.dialogVisible, callback: newVisible => this.dialogVisible = newVisible } }} /> ) } } 複製代碼

4. vue-better-sync 插件

有需求如此:開發一個 Prompt 組件,要求同步用戶的輸入,點擊按鈕可關閉彈窗。 ui

通常咱們會這樣作:

<template>
  <div v-show="_visible">
    <div>完善我的信息</div>
    <div>
      <div>尊姓大名?</div>
      <input v-model="_answer" />
    </div>
    <div>
      <button @click="_visible = !_visible">確認</button>
      <button @click="_visible = !_visible">取消</button>
    </div>
  </div>
</template>

<script> export default { name: 'prompt', props: { answer: String, visible: Boolean }, computed: { _answer: { get() { return this.answer }, set(value) { this.$emit('input', value) } }, _visible: { get() { return this.visible }, set(value) { this.$emit('update:visible', value) } } } } </script>
複製代碼

寫一兩個組件還好,組件規模一旦擴大,寫雙向綁定真能寫出毛病來。因而,爲了解放生產力,有了 vue-better-sync 這個輪子,且看用它如何改造咱們的 Prompt 組件:this

<template>
  <div v-show="actualVisible">
    <div>完善我的信息</div>
    <div>
      <div>尊姓大名?</div>
      <input v-model="actualAnswer" />
    </div>
    <div>
      <button @click="syncVisible(!actualVisible)">確認</button>
      <button @click="syncVisible(!actualVisible)">取消</button>
    </div>
  </div>
</template>

<script> import VueBetterSync from 'vue-better-sync' export default { name: 'prompt', mixins: [ VueBetterSync({ prop: 'answer', // 設置 v-model 的 prop event: 'input' // 設置 v-model 的 event }) ], props: { answer: String, visible: { type: Boolean, sync: true // visible 屬性可用 .sync 雙向綁定 } } } </script>
複製代碼

vue-better-sync 統一了 v-model.sync 傳遞數據的方式,你只需 this.actual${PropName} = newValue 或者 this.sync${PropName}(newValue) 便可將新數據傳遞給父組件。spa

相關文章
相關標籤/搜索