vue系列(一)

本文最后更新于 2025年1月26日 凌晨

前言

在此次Vue 3.4的更新忠,最引人注目的莫过于defineModel的正式登场。此新特性是对Vue组件间通信机制的一次重要升级,旨在简化双向数据绑定的实现,让开发者能够以更优雅、高效的方式处理父子组件间的状态共享。

vue2中的v-model的使用与实现方式

v-mode本质是一种语法糖,它简化了表单控件与数据之间的双向绑定过程,在vue2中 其是v-bind:value 与 @input 的 一种简写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// 绑定单个数据 --------------------------------------
<!--v-model写法-->
<input v-model="message">
<!--等价于-->
<input :value="message" @input="message = $event.target.value">

// 自定义组件绑定多个数据 --------------------------------------
<!--父组件-->
<son-com :first="first"
:second="second"
@update:first="toUpdateFirstDateHandler"
@update:second="toUpdateSecondDateHandler">
</son-com>


<!-- SonCom.vue -->
<template>
<!-- 假设这里有一些与first和second相关的交互 -->
</template>
<script>
export default {
props: ['first', 'second'],
data() {
return {
// 内部状态,如果有的话
};
},
watch: {
first(newVal) {
this.$emit('update:first', newVal); // 监听first变化
},
second(newVal) {
this.$emit('update:second', newVal); // 监听second变化
}
},
// 或者在methods中根据具体逻辑触发事件
}
</script>

可以看到,如果想要更新一些状态,过程还是比较繁琐的,vue2后续又出现了一个修饰符 .sync ,简化了父组件的绑定操作,比如双向绑定多个状态可以改写为:

1
2
3
<son-com :first.sync="first" 
:second.sync="second">
</son-com>

vue3中的v-model的使用

vue3的v-model相比vue2来说 更加友好,

  1. 其语法糖由默认的 :value 与@input 改变未 :modelValue 与@uptate:modelValue, 你可以自定义触发的事件名称。
  2. v-mode可以直接绑定数组或者对象的属性值,例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<my-component v-model="user.name"></my-component>
<script setup>
const user = ref({
name:'wang'
})
</script>

// my-component
<template>
<input type="text" :value="props.modelValue" @input="updateName($event.target.value)">
<!-- 或其他逻辑,根据组件需要更新modelValue -->
</template>

<script setup>
const props = defineProps({
modelValue: {
type: String,
default: ''
}
});

const emit = defineEmits(['update:modelValue']);
// 更新modelValue的函数
const updateName = (newValue) => {
emit('update:modelValue', newValue);
};
</script>

vue3.4中的defineModel的使用

下面是defineModel的简单使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<my-component v-model:person="person" v-model:job="job"></my-component>


// my-component
<template>
<input type="text" v-model="person">
<input type="text" v-model="job">
<!-- 或其他逻辑,根据组件需要更新modelValue -->
</template>

<script setup>
const person = defineModel('person')
const job = defineModel('job')
</script>

defineModel看似是违背了数据的单项流动原则 其实不然 ,该宏函数只是隐藏了制造中间变量去接受prop的值与更新input绑定的值的过程,
其本质可以简化为以下模型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<template>
<input v-model="model" />
</template>

<script setup lang="ts">
import { ref, watch } from "vue";

const props = defineProps(["modelValue"]);
const emit = defineEmits(["update:modelValue"]);
const model = ref();

watch(
() => props.modelValue,
() => {
model.value = props.modelValue;
}
);
watch(model, () => {
emit("update:modelValue", model.value);
})
</script>

结语

vue3.4版本的更新 除了带来了defineModel这个宏函数 ,还做了计算属性的优化与模板解析的优化,其中还有v-bind的同名简写(比如,:name=’name’ 现在可以简写为 :name),是一次比较全面的更新,
对开发者更友好,对性能也有很大的提升,有条件的,可以将vue版本更新至3.4以上。

vue3.4官方博客更新介绍


vue系列(一)
https://www.wenhai.life/2024/06/22/24062201/
作者
wen Hai
发布于
2024年6月22日
许可协议