1. 程式人生 > >Vue元件實現v-model的用法

Vue元件實現v-model的用法

簡單說明

當我們封裝一個元件,比如說MySelect元件,我們希望他的用法是這樣的。

<my-select v-model="job">
  <my-option value="dev">開發人員</my-option>
  <my-option value="test">測試人員</my-option>
  <my-option value="manager">管理人員</my-option>
</my-select>

這個用法很普遍,因為Vue本身對錶單元素的雙向繫結就是這麼使用的。但封裝這樣的元件我遇到最大的問題就是:無法對props中的value進行改變


所以我們需要先了解一下v-model的實現,下面就詳細說一下v-model的實現。

Vue對v-model的實現

如果我們不用v-model來實現雙向繫結,那麼我們需要這樣寫:

<template>
  <input type="text" v-bind:value="name" @input="inputHandler"/>
<template>
<script>
  export default {
    data(){
      return {
        name: ''
      }
    },
    methods: {
inputHandler(value){ if(value == null){ this.name = event.target.value; } else{ this.name = value; } } } }
</script>
  • 我們通過vue的v-bind指令為input綁定了value,那麼在name值發生改變時,input的value也會發生改變。這樣就實現了資料驅動DOM。(至於vue提供的bind是如何實現的,可以去了解一下Object.defineProperties
  • 我們為input綁定了input事件,在事件處理函式中將event.target.value賦值給name。這樣就實現了DOM驅動資料的改變。

基於這兩個實現,就實現了DOM和資料的雙向繫結。很慶幸Vue對v-model的實現就是這樣的(跟官網的描述有些許不同,僅供參考)。可以看出,v-model實際上是通過:value@input來實現的。並且inputHandler中優先以傳入的引數value值給我們繫結的變數賦值,這一點很重要。這使得我們在元件中可以直接通過this.$emit('input', newValue)來給外界的data屬性賦值。

綜上所述,我們簡單的對my-select元件進行封裝

my-select元件的封裝(未測試