Vue v-model語法糖

wdapp發表於2020-02-17

v-model語法糖

我們可以使用v-model對input進行雙向繫結

 <input v-model="message"></input>
複製程式碼

v-model 語法糖本質是 :value="message" @input="onInput"

<input :value="message" @input="onInput"></input>
複製程式碼

如果使子元件接收 props: value 並且 $emit('input', value) 事件,那麼就直接使用v-modle語法糖

<div id="app">
  {{message}}
  <field :value="message" @input="onInput"></field>
  <field v-model="message"></field>
</div>
複製程式碼

:value="message" @input="onInput" 與 v-model="message" 效果相同

field子元件:

 Vue.component('field', {
    props: {
      value: {
        type: String
      }
    },
    template: `
      <input :value="value" @input="onInput">
    `,
    methods: {
      onInput (e) {
        var value = e.target.value
        this.$emit('input', value)
      }
    }
  })
複製程式碼

vue例項:

var app = new Vue({
    el: '#app',
    data: {
      message: 'hello vue !'
    },
    methods: {
      onInput (val) {
        this.message = val
      }
    }
  })
複製程式碼

model

如果使用v-model想要監聽checkbox的onchange事件,則需要model來自定義v-model語法糖

Vue.component('checkbox', {
    model: {
      prop: 'checked',
      event: 'change'
    },
    props: {
      checked: {
        type: Boolean,
        default: false
      }
    },
    template:
          `
      <input type="checkbox" @input="onInput" @change="onChange"/>
    `,
    methods: {
      onInput (e) {
        console.log('onInput', e)
      },
      onChange (e) {
        console.log('onChange', e)
        this.$emit('change', e.target.checked)
      }
    }
  })
複製程式碼

由於v-model需要在props裡面定義value來接受值,emit input來更新值,所以需要model來重新自定義prop和event

使用checkbox元件

 <checkbox v-model="toggle"></checkbox>
  <p v-show="toggle">hello</p>
複製程式碼

vue例項:

  var app = new Vue({
    el: '#app',
    data: {
      message: 'hello vue !',
      toggle: false
    },
    methods: {
      onInput (val) {
        this.message = val
      }
    }
  })
複製程式碼

完整程式碼:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>v-model語法糖</title>
  <script src="js/vue.js"></script>
</head>
<body>
<div id="app">
  {{message}}
  <field :value="message" @input="onInput"></field>
  <field v-model="message"></field>
  <checkbox v-model="toggle"></checkbox>
  <p v-show="toggle">hello</p>
</div>
<script>
  /**
   * v-model 語法糖本質是 :value="message" @input="onInput"
   * 如果使用v-modle語法糖,則需要子元件接收 props: value 並且 $emit('input', value) 事件
   */
  Vue.component('field', {
    props: {
      value: {
        type: String
      }
    },
    template: `
      <input :value="value" @input="onInput">
    `,
    methods: {
      onInput (e) {
        var value = e.target.value
        this.$emit('input', value)
      }
    }
  })
  /**
   * model
   * 如果使用v-model想要監聽checkbox的onchange事件,則需要model來自定義v-model語法糖
   * 由於v-model需要在props裡面定義value來接受值,emit input來更新值,所以需要model來重新自定義prop和event
   */
  Vue.component('checkbox', {
    model: {
      prop: 'checked',
      event: 'change'
    },
    props: {
      checked: {
        type: Boolean,
        default: false
      }
    },
    template:
          `
      <input type="checkbox" @input="onInput" @change="onChange"/>
    `,
    methods: {
      onInput (e) {
        console.log('onInput', e)
      },
      onChange (e) {
        console.log('onChange', e)
        this.$emit('change', e.target.checked)
      }
    }
  })
  var app = new Vue({
    el: '#app',
    data: {
      message: 'hello vue !',
      toggle: false
    },
    methods: {
      onInput (val) {
        this.message = val
      }
    }
  })
</script>
</body>
</html>

複製程式碼

相關文章