vue.js自定義組件上使用v-model

前言

vue2.2+版本新增了一個功能,能夠在自定義組件上使用v-model實現雙向綁定。在使用新功能以前,咱們先來了解一下vue.js的v-model是如何實現雙向綁定的。從官方文檔以及各類技術文章中,咱們能夠知道,v-model是v-bind以及v-on配合使用的語法糖,給一個詳細的例子:vue

<input v-model="value" />
<input v-bind:value="value" v-on:input="value= $event.target.value" />
複製代碼

兩種方法的實現效果是同樣的,都是給<input>標籤綁定一個值,而且在監聽到input事件時,把輸入的值替換綁定的值來實現雙向綁定。其中第一種是第二種方法的語法糖。bash

如今咱們已經瞭解了v-model是什麼東東,那麼除了在表單控件上使用v-model外,能不能在自定義的組件上使用v-model,從而實現父子組件間的雙向綁定呢?app

答案是能夠的。 vue2.2+版本後,新增長了一個model選項,model選項容許自定義prop和event。官方原文是這樣的:容許一個自定義組件在使用 v-model 時定製 prop 和 event。默認狀況下,一個組件上的 v-model 會把 value 用做 prop 且把 input 用做 event,可是一些輸入類型好比單選框和複選框按鈕可能想使用 value prop 來達到不一樣的目的。使用 model 選項能夠迴避這些狀況產生的衝突。ui

下面咱們經過一個實例來說解怎麼使用:this

咱們首先編寫一個子組件,並用到model選項,核心代碼以下:spa

<template>
  <div class="radio">
    <div class="radioGroup">
      <div
        class="radioItem"
        v-for="item in options"
        :key="item.value"
        @click="clickRadio(item.value);"
      >
        <div
          class="radioBox"
          :class="{ checked: item.value === checked }"
        ></div>
        <div class="name">{{ item.name }}</div>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  name: "radio",
  props: {
    options: Array,
    value: Number
  },
  computed: {
    checked() {
      return this.value;
    }
  },
  model: {
    prop: "value", //綁定的值,經過父組件傳遞
    event: "update" //自定義時間名
  },
  methods: {
    clickRadio(val) {
      this.checked = val;
      this.$emit("update", val); //子組件與父組件通信,告知父組件更新綁定的值
    }
  },
  watch: {
    checked: function(newVal, oldVal) {
      console.log("我是子組件,如今的值爲:" + newVal);
      alert("我是子組件,如今的值爲:" + newVal);
    }
  }
};
</script>
複製代碼

父組件部分:雙向綁定

<template>
  <div id="app">
    <div class="left">選中:{{checked}}</div>
    <radio class="right" :options="options" v-model="checked"></radio>
  </div>
</template>

<script>
import radio from './components/radio.vue'

export default {
  name: 'App',
  components: {
    radio
  },
  data() {
    return {
      checked: 0,
      options: [{
        value: 0,
        name: '選項1'
      }, {
        value: 1,
        name: '選項2'
      }]
    }
  }
}
</script>
複製代碼

demo地址code

源碼地址component

相關文章
相關標籤/搜索