vue v-model双向绑定解析
首先父组件:
<jk-test :posts="posts" name="test" v-model="val" ></jk-test>
子组件:
Vue.component('jk-test', { model: { event: 'change', prop: 'value', }, props: ['posts', 'name', 'value'], template: ` <select :name="name" v-bind:value="value" v-on:change="$emit('change', $event.target.value)" > <option v-for="item in posts" :key="item.text" :label="item.text" :value="item.text"> </option> </select> `, })
整个值传递示意图:
首先父组件的v-model相当于 :value="val" @change="val = $event.target.value"
这样就将父组件的val值绑定到了子组件的value属性上,这样子组件的value会跟着val的值改变而改变,val变化->value变化 可以了,接下来就是value变化->val变化,
当我准备故技重施在子组件里使用v-model="value"时却报错了:
大致意思就是不要直接修改组件属性的值,那怎么办,那就只能修改能修改value的值了,这就是父组件的val值,现在父组件的@change="val = $event.target.value"的作用就体现出来了,这里父组件监听一个change事件并根据change事件的回调值反映的数据来修改val值,那change事件在哪里呢,当然是在子组件里定义了:@change="$emit('change', $event.target.val)",这样在子组件的值发生变化的时候就会触发change事件,而change事件会执行$emit('change',$event.change.val)这段代码会触发当前实例上的change事件,并且改变的值会传给监听器回调,这样父级的@change="val = $event.target.value"就能成功获取改变的值并修改val了,然后val修改了子组件的value自然也就跟着修改了,这样就完成了子组件和父组件的双向绑定,虽然说是双向绑定,但实际上首先改变的值一直都是val,然后再由val改变value
父组件修改子组件的值直接使用v-bind即可
子组件修改父组件的值需要:
1、子组件change事件触发实例事件(change)并将变化的数据传给监听器回调
2、父组件监听子组件的特定事件(change)并获取回调参数获取变化的值
3、父组件修改跟子组件value绑定的数据
这里有一个容易混淆的地方:子组件的
v-on:change="$emit('change', $event.target.value)"
为什么会有两个change,这两个change时间分别是谁的事件?
首先v-on:change,这里的change是select的这个实例的事件
而$emit('change',$event.target.value)里的change事件是整个子组件实例的事件,也就是父组件@change监听的事件
所以子组件中无论有多少个select触发了change事件那也只是触发的自己实例(select)的change事件,只有使用$emit触发的事件才是当前子组件这个整体的change事件