
让我们一起走向未来
🎓作者简介:全栈领域优质创作者
🌐个人主页:百锦再@新空间代码工作室
💡座右铭:坚持自己的坚持,不要迷失自己!要快乐

目录
- 让我们一起走向未来
- 1. `defineProps` 与 `.value` 的关系
- 1.1 `defineProps` 基本用法
- `.value` 的使用
- 1.2 使用 `.value` 的原因
- 1.3 为什么有时候不需要 `.value`
- 2. `defineModel` 和 `.value` 的关系
- 2.1 `defineModel` 基本用法
- 2.2 使用 `.value` 的原因
- 2.3 为什么有时不需要 `.value`
- 3. 什么时候需要 `.value`,什么时候不需要
- 3.1 需要 `.value` 的情况
- 3.2 不需要 `.value` 的情况
- 4. 总结

Vue 3 引入了 Composition API,defineModel 和 defineProps 是其中两个关键的 API,它们主要用于在组件中定义响应式状态和接受外部传递的属性。理解这些 API 如何工作,以及在什么情况下需要使用 .value 来获取值,对于编写清晰、健壮的 Vue 代码非常重要。
1. defineProps 与 .value 的关系

1.1 defineProps 基本用法
在 Vue 3 中,defineProps 是 Composition API 中用于定义组件的 props 的一个函数。通过 defineProps,你可以声明组件接收哪些 props,并且这些 props 会自动成为响应式的。
<script setup>
import { defineProps } from 'vue';
const props = defineProps({
msg: String,
});
</script>
<template>
<div>{{ props.msg }}</div>
</template>这里,defineProps 会返回一个响应式对象,这意味着 props.msg 会随着父组件传递给子组件的 msg 值的变化而自动更新。
.value 的使用

defineProps 返回的对象是一个响应式引用(ref),这意味着我们需要使用 .value 来访问它的值。
const msg = defineProps({
msg: String,
});
console.log(msg.value); // 访问msg的值这种方式的目的是在 Composition API 中保持一致性,因为 ref 是 Vue 3 中用来创建响应式数据的基本方式。在其他地方,像 reactive 返回的对象不会用 .value 来访问,而是直接访问属性,只有 ref 类型的数据需要用 .value 来解引用。
1.2 使用 .value 的原因
- 响应式引用(ref)的设计:Vue 3 中的
ref是用来包裹单一值的响应式容器。当你使用defineProps或ref()创建的变量时,返回的是一个具有.value属性的对象,这是 Vue 3 的设计哲学之一。为了避免直接操作响应式对象,Vue 让你通过.value来显式地访问或修改它。 - TypeScript 支持:TypeScript 通过
.value让你明确知道某个变量是一个响应式引用,这样可以避免类型推断错误。
1.3 为什么有时候不需要 .value

defineProps 返回的响应式对象有时会直接在模板中被解构,因此你不需要手动访问 .value。在 Vue 的模板中,props 对象会自动解构并进行响应式跟踪,不需要使用 .value,这是 Vue 自动处理的事情。
<template>
<div>{{ msg }}</div> <!-- 这里直接使用 msg,不需要 .value -->
</template>
<script setup>
const { msg } = defineProps({
msg: String,
});
</script>在这种情况下,Vue 会自动处理对 msg 的响应式依赖,因此你不需要显式地使用 .value。
2. defineModel 和 .value 的关系

2.1 defineModel 基本用法
defineModel 主要用于在父子组件之间双向绑定数据。它和 v-model 指令类似,但是使用 Composition API 方式进行绑定。defineModel 允许你定义组件中需要双向绑定的属性和事件。
<script setup>
import { defineModel } from 'vue';
const modelValue = defineModel('modelValue', {
type: String,
default: '',
});
</script>
<template>
<input v-model="modelValue" />
</template>在这个例子中,defineModel 定义了一个 modelValue 属性,通常用来实现父子组件之间的双向绑定。通过 v-model,Vue 会自动处理 modelValue 和 update:modelValue 事件。
2.2 使用 .value 的原因

defineModel 返回的也是一个响应式引用类型。由于 modelValue 是一个 ref 类型的数据,所以如果你在 JavaScript 代码中直接访问或修改它的值,必须使用 .value:
console.log(modelValue.value); // 访问 modelValue 的值
modelValue.value = 'new value'; // 修改 modelValue 的值2.3 为什么有时不需要 .value

在模板中使用 defineModel 时,Vue 会自动处理 .value 的解引用。你可以直接在模板中使用 modelValue,而 Vue 会帮你处理 ref 对象的访问。
<template>
<input v-model="modelValue" />
</template>
<script setup>
import { defineModel } from 'vue';
const modelValue = defineModel('modelValue', {
type: String,
default: '',
});
</script>在这种情况下,Vue 会自动将 v-model="modelValue" 转化为对 modelValue.value 的引用,因此在模板中你不需要显式地使用 .value。
3. 什么时候需要 .value,什么时候不需要

3.1 需要 .value 的情况
- 在 JavaScript 代码中操作
ref:当你在<script>中访问或修改ref对象时,需要使用.value。例如:
const msg = defineProps({ msg: String });
console.log(msg.value); // 正确访问 props
msg.value = 'new message'; // 修改值- 在响应式数据中传递值时:如果你把
ref的值传递给其他函数或者组件,依然需要通过.value来访问实际值。例如:
const count = ref(0);
const updateCount = (newCount) => {
count.value = newCount; // 使用 .value 修改 count 的值
};- 在
watch或computed中使用ref:当你在watch或computed中观察或计算ref的值时,同样需要通过.value获取值。
watch(() => count.value, (newCount) => {
console.log('Count changed to: ' + newCount);
});3.2 不需要 .value 的情况

- 在模板中直接使用
props和modelValue:在模板中,Vue 会自动处理ref和响应式对象的解引用,因此不需要手动加.value。只需要直接使用变量即可:
<template>
<div>{{ msg }}</div> <!-- Vue 会自动解引用 msg -->
</template>- 在解构赋值时:当你使用
defineProps或defineModel并进行解构时,Vue 会自动将解构出来的变量变成普通的响应式变量,不需要加.value:
const { msg } = defineProps({
msg: String,
});- 在 Vue 的
v-model中:如果你使用的是v-model,Vue 会自动处理.value,你不需要显式地使用它:
<input v-model="modelValue" />4. 总结

-
defineProps和defineModel返回的对象通常是ref类型的响应式对象,因此你需要使用.value来访问和修改它们的值,尤其是在 JavaScript 代码中。 - 在模板中,Vue 会自动处理
.value,所以你可以直接使用变量而无需显式加.value。 - 理解何时需要
.value和何时不需要.value是理解 Vue 3 响应式系统的关键。
通过清晰的理解 Vue 响应式系统,特别是 ref 和 reactive 的使用方式,你将能够编写更加优雅和高效的代码。










