vue 自定义组件使用v-model

<input v-model="something">是我们常用的双向绑定方法,如果在自定义组件中如何使用v-model进行双向绑定呢?

首先我们必须要清除v-model绑定的原理如下:
其实v-model的语法糖是这样包装而成的:
<input
  :value="something"
  @:input="something = $event.target.value">
而一个组件上使用时则会简化成这样子:
<custom-input
  :value="something"
  @input="value => { something = value }">
</custom-input>

因此,对于一个带有 v-model 的组件(核心用法),它应该如下:

  • 带有v-model的父组件通过绑定的value值(即v-model的绑定值)传给子组件,子组件通过 prop接收一个 value;
  • 子组件利用 $emit 触发 input 事件,并传入新值value给父组件;

this.$emit('input', value);
废话不多说了,直接上栗子;
HTML:
<div id="app">
  <my-component v-model="msg"></my-component>
  msg: {{msg}}
  <my-counter v-model="num"></my-counter>
  num: {{num}}
</div>
JS:
Vue.component('my-component', {
  template: `<div>
  <input type="text" :value="currentValue" @input="handleInput"/>
  </div>`,
  data: function () {
    return {
      currentValue: this.value //将prop属性绑定到data属性上,以便修改prop属性(Vue不允许直接修改prop属性的值)
    }
  },
  props: ['value'], //接收一个 value prop
  methods: {
    handleInput(event) {
      var value = event.target.value;
      this.$emit('input', value); //触发 input 事件,并传入新值
    }
  }
});
Vue.component("my-counter", {
  template: `<div>
  <h1>{{value}}</h1>
  <button @click="plus">+</button>
  <button @click="minu">-</button>
  </div>`,
  props: {
    value: Number //接收一个 value prop
  },
  data: function() {
    return {
      val: this.value 
    }
  },
  methods: {
    plus() {
      this.val = this.val + 1
      this.$emit('input', this.val) //触发 input 事件,并传入新值
    },
    minu() {
      if(this.val>0){
        this.val = this.val-1
        this.$emit('input', this.val) //触发 input 事件,并传入新值
      }
    }
  }
});
new Vue({
	el: '#app',
  data: {
  	msg: 'hello world',
    num: 0
  }
})

  Demo截图:

demo实例详情

 

注意:

1.带有v-model绑定的父组件下的子组件不一定是要input标签的元素,其他元素都可以;  

2.将prop属性绑定到data属性上,以便修改prop属性(Vue不允许直接修改prop属性的值);

3.实现双向绑定是watch监听属性是一个不做的方法(实时监视值的变化);(详细用法

 

posted @ 2018-01-21 23:48  咖啡爱上茶  阅读(12911)  评论(0编辑  收藏  举报