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

相关文章
相关标签/搜索