悟空阅读app
103.67MB · 2025-11-20
绑定属性时,即使绑定的值是常量 false,也需要使用 : 前缀。关键认知:: 的作用是区分字符串 vs JavaScript 值,而非 “固定值 vs 变量”。
:(HTML 属性)<el-form hide-required-asterisk="false">
props.hideRequiredAsterisk = "false"(字符串类型)if ("false") 会执行,最终等效于 true:(JavaScript 表达式)<el-form :hide-required-asterisk="false">
props.hideRequiredAsterisk = false(布尔类型)if (false) 不会执行,符合预期效果| 代码写法 | 解析结果 | 是否正确 |
|---|---|---|
<el-form hide-required-asterisk="false"> | 等效于 :hide-required-asterisk="'false'" | |
<el-form :hide-required-asterisk="'false'"> | 等效于 :hide-required-asterisk="true" | |
<el-form :hide-required-asterisk="false"> | 解析为布尔值 false |
: 的真正作用告诉 Vue:“把引号里的内容当作 JavaScript 代码执行,而非字符串”。
:)<el-input placeholder="请输入">
placeholder = "请输入"(字符串类型):)<el-input :maxlength="100">
maxlength = 100(数字类型,非字符串 "100"):)<el-form :hide-required-asterisk="false">
hideRequiredAsterisk = false(布尔类型):)<el-form :model="{ name: 'test' }">
model = { name: 'test' }(对象类型):)<el-form :hide-required-asterisk="isReadOnly">
hideRequiredAsterisk = isReadOnly(变量对应的值)<el-form :hide-required-asterisk="false">
false 是固定值,此表述正确:,原因是要传递布尔类型(JavaScript 值),而非字符串: 的核心依据是值的类型,而非 “是否会变化”: 的核心作用是区分 “字符串” 与 “JavaScript 代码执行结果”,而非 “固定值 vs 变量”。本质:: 表示 “这是 JavaScript 代码,请执行它”。
Vue3 中 computed 函数是否会在 “依赖更新” 和 “视图渲染” 时多次触发?为何与 React useMemo 行为不同?这一差异的本质是框架响应式设计理念的区别吗?
Vue3 computed 函数仅在依赖数据变化时重新执行,视图渲染时若依赖未变则复用缓存,不会额外触发;其与 React useMemo 的行为差异,核心是 Vue “响应式 getter 驱动” 与 React “声明式依赖数组驱动” 的设计理念不同,而非 “两次触发” 的差异。
核心定位:computed 是 “响应式的 getter”,与响应式数据(ref/reactive)深度绑定。
触发逻辑:
snapshotData.value)发生变化时,computed 函数会自动重新执行。{{ formatAmount }} 时,仅当依赖已变化,才会触发重新计算;依赖未变则直接复用缓存结果。代码示例:
const formatAmount = computed(() => {
console.log("snapshotData.value", snapshotData.value); // 仅依赖变化时打印
return snapshotData.value ? `+${snapshotData.value.amount}` : "+0";
});
核心定位:useMemo 是 “声明式的缓存计算工具”,依赖显式配置的依赖数组。
触发逻辑:
{formatAmount} 仅为读取缓存值,无论视图如何渲染,只要依赖未变,都不会重新执行计算函数。代码示例:
const formatAmount = useMemo(() => {
console.log("snapshotData", snapshotData); // 仅依赖数组变化时打印
return snapshotData ? `+${snapshotData.amount}` : "+0";
}, [snapshotData]); // 显式依赖数组
| 特性 | Vue3 Computed | React useMemo |
|---|---|---|
| 核心定位 | 响应式 getter | 声明式缓存计算工具 |
| 触发时机 | 依赖响应式数据变化时 | 依赖数组变化 / 组件首次渲染时 |
| 视图使用时 | 依赖已变则重新计算,否则复用缓存 | 仅读取缓存值,不触发重新计算 |
| 依赖配置 | 自动追踪响应式依赖,无需手动配置 | 需显式声明依赖数组 |
| 内部打印行为 | 依赖变化时打印(与计算执行同步) | 依赖数组变化时打印(仅执行一次) |
并非 “依赖更新 + 视图渲染” 两次触发,而是:
snapshotData.value)为初始值(如 null),computed 执行一次并打印。{ amount: 100 }),computed 再次执行并打印。watchEffect 专门监听数据变化,替代 computed 内打印。watchEffect(() => {
console.log("snapshotData 变化了:", snapshotData.value); // 仅监听变化打印
});
const handleSubmit = () => {
snapshotData.value = { amount: formData.amount };
console.log("快照数据更新:", snapshotData.value); // 源头打印更精准
};
reactive reactive 是 Vue 3 Composition API 中用来创建响应式对象的核心函数,作用是让数据具备 “变化自动触发视图更新” 的特性。
响应式意味着:当数据变化时,使用这些数据的地方(如模板、计算属性等)会自动更新。
import { reactive } from "vue";
// 创建响应式对象
const state = reactive({
count: 0,
message: "Hello"
});
// 数据修改后,依赖该数据的视图自动更新
state.count++;
const formData = reactive({
adjustType: 1, // 调整类型(+/-)
amount: undefined, // 金额
remark: "" // 说明
});
v-model="formData.amount" 时,用户输入会自动同步到 formData.amount。{{ formatAmount }} 依赖 formData,会随数据变化自动更新。<template>
<!-- 1. 显示数据:依赖 formData.amount -->
<div>金额:{{ formData.amount }}</div>
<!-- 2. 修改数据:v-model 绑定响应式属性 -->
<input v-model="formData.amount" />
</template>
<script setup>
import { reactive } from "vue";
const formData = reactive({
amount: 0
});
// 3. 输入框值改变 → formData.amount 自动更新 → 模板显示同步更新
</script>
reactive vs 普通对象| 类型 | 代码示例 | 响应式效果 |
|---|---|---|
| 普通对象 | const formData = { amount: 0 }; formData.amount = 300; | 模板不会更新 |
| 响应式对象 | const formData = reactive({ amount: 0 }); formData.amount = 300; | 模板自动更新 |
reactive 的核心特点仅支持对象类型
reactive({ count: 0 })、reactive([1,2,3]))。reactive(0) 无效,需用 ref)。深层响应式嵌套对象的属性同样具备响应式,修改任意层级属性都会触发更新:
const state = reactive({
user: {
name: "张三",
address: { city: "上海" }
}
});
state.user.address.city = "北京"; // 触发响应式更新
.value,直接读写属性即可:const formData = reactive({ amount: 300 });
console.log(formData.amount); // 300(直接访问)
formData.amount = 500; // 直接赋值修改
reactive vs ref 对比| 特性 | reactive | ref |
|---|---|---|
| 适用类型 | 对象、数组等复杂类型 | 任何类型(基本类型、对象) |
| 访问方式 | 直接访问:state.count | 脚本中需 .value:count.value |
| 模板中使用 | {{ state.count }} | {{ count }}(自动解包,无需 .value) |
| 解构特性 | 直接解构会失去响应式 | 配合 toRefs 可保持响应式 |
import { reactive, ref } from "vue";
// reactive 用法(对象)
const formData = reactive({ amount: 0 });
formData.amount = 300;
// ref 用法(基本类型)
const count = ref(0);
count.value = 300;
const formData = reactive({ adjustType: 1, amount: undefined, remark: "" });
const state = reactive({ user: null, isLoading: false, error: null });
state.isLoading = true; // 状态变化触发视图更新
const todoList = reactive({ items: [], filter: "all" });
todoList.items.push({ id: 1, text: "学习 Vue 3" }); // 列表更新自动渲染
禁止直接解构
const { count } = reactive({ count: 0 }); count++(失去响应式)。toRefs 保持响应式:import { toRefs } from "vue";
const state = reactive({ count: 0 });
const { count } = toRefs(state);
count.value++; // 正常触发更新
不能整体替换对象
let state = reactive({ count: 0 }); state = reactive({ count: 100 })(原响应式关联失效)。Object.assign:state.count = 100; // 直接修改属性
Object.assign(state, { count: 100 }); // 合并更新
reactive 的核心价值是为对象类型数据添加 “自动响应式” 能力:
ref,reactive 仅适用于复杂对象类型。