(自用)共学小黄鸭:v-model

282 阅读2分钟

一、前提概要

在Vue2->Vue3的过程中,在修改界面中的对话框相关属性,即将:visible.sync改为v-model:visible的过程中发现:当点击展示对话框的按钮后,对话框并没有进行展示。

二、知识点

1、v-model的本质

v-model 是 Vue.js 提供的一种语法糖,用于实现表单元素的双向绑定。它的本质是通过 :value 属性和 @input 事件的结合,简化了表单元素数据的绑定。

当你在一个元素上使用 v-model 时,例如:

<input v-model="message">

它的内部实际上被转换为:

<input :value="message" @input="message = $event">

这里的 :value 是将元素的值与 Vue 实例的数据属性 message 进行绑定,而 @input 则是监听输入事件,当输入框的值发生变化时,将新的值赋给 message

2、v-model:visible和:visible的区别

2.1 :visible (单向绑定)

这是一个属性绑定,用于将父组件中的数据绑定到子组件的 visible 属性上。例如:

<child-component :visible="isVisible"></child-component>

在子组件中,你需要使用 props 来声明 visible 属性,并在组件内部使用:

props: ['visible'],

2.2 v-model:visible (双向绑定)

这是一种用于处理子组件与父组件之间双向绑定的语法糖。v-model 通常用于绑定表单元素的值,但你可以通过 v-model:visible 这样的写法,实现对自定义属性的双向绑定。例如:

<child-component v-model:visible="isVisible"></child-component>

在子组件中,你需要使用 props 接收 visible 属性,并触发 update:visible 事件,使得父组件中的数据发生变化。例如:

props: ['visible'],
// ...
methods: {
  handleVisibleChange() {
    this.$emit('update:visible', !this.visible);
  }
}

在父组件中,你可以通过 v-model:visible 来双向绑定 isVisible

而在子组件中,你可以通过this.$emit('update:visible', !this.visible)来更新父组件中的值。这行代码是在 Vue 组件中使用 $emit 方法触发一个自定义事件,这里的事件名称是 'update:visible',并传递了一个新的值 !this.visible 给父组件。

本质: 在 Vue 中,如果一个组件使用了 v-model 来绑定一个属性,Vue 会默认使用名为 update:xxx 的事件来处理这个绑定,简单来说,'update:visible' 是一个约定俗成的命名,它表示对 visible 属性进行更新。

3、改版过程中关于v-model的问题是如何解决的

一开始我是通过在网络上搜索,找到了一个解决方案,即在子组件中加上以下两行代码,即可解决该问题。

img_v3_027e_6b0c3ef3-836a-430a-91db-6f2cc463c71g.jpg

img_v3_027e_32929f45-0ea2-4675-bc61-9a0467d86b9g.jpg

进而我去了解了v-model的本质后,也理解了该种解决方法的本质了。 然后我又去翻了我带教老师的代码,他的写法如下:

父组件中:

v-model="xxx"

子组件中:

this.$emit('update:model-value':xxx)

本质: 在 Vue.js 中,:model-value 是 Vue 2.x 中用于实现双向绑定的一种约定。这个名称是为了让开发者能够在自定义组件中使用 v-model 指令。

在Vue3中,当你在一个组件上使用 v-model 指令时,Vue 会默认将一个名为 modelValue 的 prop 和一个名为 update:modelValue 的事件传递给该组件。你可以在组件中使用这两者来实现双向绑定

4、.sync修饰符

4.1 Vue2中.sync修饰符

在 Vue 2 中,.sync 修饰符是为了实现子组件与父组件之间的双向绑定。它简化了通过 props 向子组件传递数据并通过事件向父组件传递变化的过程。

当你在子组件上使用 .sync 修饰符时,Vue 会自动为你创建一个子组件的 update: 事件,这个事件用于在子组件中触发并向父组件传递变化。

4.2 Vue3中.sync修饰符

Vue3中去掉了.sync修饰符,它的功能可以由v-model的参数来替代。

5、多个v-model

Vue3允许多个v-model,但是在Vue2不可以写多个v-model

6、开发的组件如何支持v-model(高频面试题)

在定义 vue 组件时,可以提供一个 model 属性,用来定义该组件以何种方式支持 v-model

model 属性本身是有默认值的,如下:

//默认的model属性
export default {
    model: {
       prop: 'value',
       event: 'input'
   }
}

如果你不定义 model 属性,或者你按照当面方法定义属性,当其他人使用你的自定义组件时,v-model="foo" 就完全等价于 :value="xxx" 加上 @input="xxx = $event"

如果把 model 属性进行一些改装,如下:

//默认的model属性
export default {
    model: {
       prop: 'a',
       event: 'b'
   }
}

经过以上改造后,v-model="a" 就等价于 :a="xxx" 加上 @b="xxx = $event"

三、参考内容

vue2 Vue3 v-model 原理 - 掘金

面试官:你真的了解 v-model 吗?(vue2) - 掘金

Vue3官方文档