**经典面试题:请阐述一下
v-model
的原理**
经典面试题:请说一下vue2与vue3在使用 v-model 时的异同点
经典面试题:请列举 vue2/vue3 的父子组件的数据双向绑定的多种写法
** 本文即可将上述三个面试题阐述清楚,并提供具体案例来让小伙伴们加深理解、彻底掌握!本文较长,小伙伴们可以先收藏+关注,抽空学习哦~💕**
💟 上一篇文章 Vue2中父子组件互相传值和方法调用(热榜前十)
📝 系列专栏 vue从基础到起飞
v-model
既
可以作用于表单元素,又可作用于自定义组件,无论是哪一种情况(vue2, vue3),它都是一个语法糖,最终会生成一个属性和一个事件。
当其作用于表单元素时,
vue
会根据作用的表单元素类型而生成合适的属性和事件。例如:
- text 和 textarea 元素使用
value
property 和input
事件; - checkbox 和 radio 使用
checked
property 和change
事件; - select 字段将
value
作为 prop 并将change
作为事件。
v-model
用于自定义组件
vue2的情况
v-model
也可作用于自定义组件,当其作用于自定义组件时,默认情况下,它会生成一个
value
属性和
input
事件。
子组件 HelloWorld.vue
这个子组件只是实现一个简单计数器的功能,然后我向上分发的事件名称是
update:value
。但是vue2如果使用
v-model
会自动的把这个事件名称给改成
input
。
<template>
<div class="hello">
<button @click="change(value - 1)">-</button>
<span>{{value}}</span>
<button @click="change(value + 1)">+</button>
</div>
</template>
<script>
export default {
name: "HelloWorld",
props: {
value: Number,
},
methods: {
change(val) {
this.$emit("update:value", val);
},
},
};
</script>
复制代码
APP.vue 来使用
<HelloWorld :value="inputVal" @update:value="inputVal = $event" />
等效于
<HelloWorld v-model="inputVal" />
复制代码
结果:
分析虚拟dom结果
vue2的虚拟dom查看方式是 在
mounted
中使用
this._vnode
来进行查看,然后查看componentOptions来查看组件传递的属性。
开发者可以通过组件的
model
配置来改变生成的属性和事件,例如:
修改子组件 HelloWorld.vue
<template>
<div class="hello">
<button @click="change(number - 1)">-</button>
<span>{{ number }}</span>
<button @click="change(number + 1)">+</button>
</div>
</template>
<script>
export default {
name: "HelloWorld",
props: {
number: Number,
},
model: {
prop: "number", // 默认为 value
event: "change", // 默认为 input
},
methods: {
change(val) {
this.$emit("change", val);
},
},
};
</script>
复制代码
父组件修改
<HelloWorld v-model="inputVal" />
<!-- 等效于 -->
<HelloWorld :number="inputVal" @change="data=$event" />
复制代码
效果
vue3的情况
v-model
也可作用于自定义组件,当其作用于自定义组件时,默认情况下,它会生成一个
modelValue
属性和
onUpdate:modelValue
事件。
子组件 Comp.vue
<script setup>
import { ref, } from 'vue'
const props = defineProps({
modelValue: Number
})
const emits = defineEmits(['update:modelValue']);
const change = (val) => {
emits('update:modelValue', val)
}
</script>
<template>
<button @click="change(props.modelValue - 1)">
-
</button>
<span>{{props.modelValue}}</span>
<button @click="change(props.modelValue + 1)">
+
</button>
</template>
复制代码
父组件App.vue
<script setup>
import { ref, getCurrentInstance } from 'vue'
import Comp from './Comp.vue'
const msg = ref(123);
const internalInstance = getCurrentInstance();
console.log(internalInstance)
</script>
<template>
<Comp v-model="msg"></Comp>
等效于
<Comp :modelValue="msg" @update:modelValue="msg = $event"></Comp>
</template>
复制代码
结果
虚拟dom分析
vue3 的查看虚拟dom的使用方式,是使用``getCurrentInstance`来查看, 里面的children中的props中来查看属性传递
区别
vue2和vue3都有v-model,原理都是生成一个属性和一个事件,但是也存在些区别 , 区别如下:
.sync
修饰符
vue3中的
.sync
修饰符是去掉了的,他的功能可以由
v-model
的参数替代
例如:
<!-- vue2 -->
<Comp :title="inputVal" @update:title="inputVal = $event" />
<!-- 简写为 -->
<Comp :title.sync="inputVal" />
<!-- vue3 -->
<Comp :title="inputVal" @update:title="inputVal = $event" />
<!-- 简写为 -->
<Comp v-model:title="inputVal" />
复制代码
多个v-model
在
vue3
中允许你写多个
v-model
,这也是强烈的说明了,v-model就是一个语法糖,只是帮你减少了代码量,仅此而已。
vue2
不能写多个
v-model
<ChildComponent v-model:title="pageTitle" v-model:content="pageContent" />
<!-- 是以下的简写: -->
<ChildComponent
:title="pageTitle"
@update:title="pageTitle = $event"
:content="pageContent"
@update:content="pageContent = $event"
/>
复制代码
v-model
的修饰符不同
vue2.x是自带的修饰符,但是在3.x的版本中,可以自定义修饰符哦 .在3.x中的修饰符会在当作属性传递给子组件,并且在属性中生成一个
modelModifiers
的属性。存在这个修饰符就会有对应的修饰符,并且是true,如果没有传递,那就是undefined。
示例代码:
修改子组件Comp.vue
<script setup>
import { ref, } from 'vue'
const props = defineProps({
modelValue: Number,
modelModifiers: {
default: () => ({})
}
})
const emits = defineEmits(['update:modelValue']);
const change = (val) => {
// 如果存在修饰符range2,那就多加1,减法就没有效果
if(props.modelModifiers.range2){
val ++;
}
emits('update:modelValue', val)
}
</script>
<template>
<button @click="change(props.modelValue - 1)">
-
</button>
<span>{{props.modelValue}}</span>
<button @click="change(props.modelValue + 1)">
+
</button>
</template>
复制代码
父组件使用
<Comp v-model.range2="msg"></Comp>
复制代码
效果
🚀 个人简介:6年开发经验,现任职某国企前端负责人,分享前端相关技术与工作常见问题~
💟 作 者:前端菜鸟的自我修养❣️
📝 专 栏:vue从基础到起飞
🌈 若有帮助,还请关注➕点赞➕收藏,不行的话我再努努力💪💪💪
更多专栏订阅推荐:
👍 前端工程搭建
💕 JavaScript深入研究📝 前端工作常见问题汇总
版权归原作者 前端开发菜鸟的自我修养 所有, 如有侵权,请联系我们删除。