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>
  `,
    })

整个值传递示意图:

image.png

首先父组件的v-model相当于 :value="val" @change="val = $event.target.value"

这样就将父组件的val值绑定到了子组件的value属性上,这样子组件的value会跟着val的值改变而改变,val变化->value变化 可以了,接下来就是value变化->val变化,

当我准备故技重施在子组件里使用v-model="value"时却报错了:

image.png

大致意思就是不要直接修改组件属性的值,那怎么办,那就只能修改能修改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事件

发表回复

您的电子邮箱地址不会被公开。