vue自定义组件实现v-model(含vue3)


v-model原理



v-model的原理就是: v-bind 和 v-on的语法糖

vue2组件双向绑定

第一种: v-bind(★)

原理: 子组件通过监听父组件数据,子组件改变数据之后通知给父组件

错误写法: 不可以直接修改props的值

正确写法

父组件

// Users.vue 



子组件

// Son.vue



第二种.sync修饰符(★★)

原理:
.sync:名字 是自己起的, 通过update:名字进行触发对象的事件
update:是vue为我们约定好的名称部分

父组件

// Users.vue



子组件

// Son.vue



第三种 v-model(★★★)

原理: 通过 model新属性: 配置一个 props:接受的属性, 和一个事件名

// Users.vue



子组件

// Son.vue



vue3组件双向绑定

第一种(★★)

这里子组件input 用的是 :value 和 @input
父组件

// Users.vue



子组件

// Son.vue



第二种: 通过computed计算属性(★★★)

这里用的是 v-model ,精简了 :vlaue 和@input
父组件

// Users.vue



子组件

// Son.vue



第三种: 组件绑定多个v-model

父组件

// Users.vue



子组件

// Son.vue



vue2 对比 vue3的 v-model区别

vue2在组件中这样设置:

父组件


子组件

export default {
  model: {
    prop: 'title', // v-model绑定的属性名称
    event: 'change' // v-model绑定的事件
  },
  props: {
    value: String, // value跟v-model无关
    title: { // title是跟v-model绑定的属性
      type: String,
      default: 'Default title'
    }
  },
  methods: {
    handle() {
      // 这里的 change, 对应 event
      this.$emit('change', 'xxx')
    }
  }
}

vue3在组件中这样设置

父组件




子组件

export default defineComponent({
  props: {
    modelValue: {
      type: String
    }
  },
  emits: ['update:modelValue'],
  setup(props, { emit }) {
    const newValue = computed({
      get: () => props.modelValue,
      set: (nv) => {
        console.log(nv)
        emit('update:modelValue', nv)
      }
    })

    return {
      newValue
    }
  }
})

总结:

vue2:

  1. v-model: 会把 value 用作 prop 且把 input 用作 event;
  2. 可以通过 .sync修饰符 指定传递名字
  3. 支持model: 可以指定v-model的 value属性名 和 event事件名字

组件v-model原理:



vue3:

  1. v-model: 不在绑定 value 而是 modelValue, 接受方法也不再是 input 而是 update:modelValue
  2. 组件支持多个 v-model, 并且可以指定名字 v-model:名字

组件v-model原理:



vue