一、前提概要
在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的问题是如何解决的
一开始我是通过在网络上搜索,找到了一个解决方案,即在子组件中加上以下两行代码,即可解决该问题。
进而我去了解了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"。