
在 vue 3 composition api 中,直接对 `useform` 返回的响应式数组进行 `.map()` 操作无法自动追踪变化;需改用 `computed` 声明派生数据,才能确保其随源数组实时更新。
在使用 @inertiajs/inertia-vue3 的 useForm(或类似表单工具)时,开发者常希望基于表单字段(如 form.ranks)动态生成衍生数据,例如用于下拉选项的 ranks_options。但若像以下方式直接赋值:
const form = useForm({
name: null,
ranks: [],
});
function addRanks() {
form.ranks.push({ name: null, id: null });
}
// ❌ 错误:非响应式,不会随 form.ranks 变化而更新
const ranks_options = form.ranks.map(value => value.name);这段代码的问题在于:form.ranks.map(...) 是一次性执行的普通数组映射操作,返回的是一个静态数组。即使后续通过 addRanks() 修改了 form.ranks,ranks_options 也不会重新计算——它失去了与源数据的响应式连接。
✅ 正确做法是将其声明为 计算属性(computed):
import { computed } from 'vue';
// ✅ 正确:响应式派生,自动追踪 form.ranks 及其内部属性
const ranks_options = computed(() =>
form.ranks.map(item => item.name)
);computed 会将 form.ranks(及其每个元素的 name 属性)作为依赖项进行追踪。当 form.ranks 被 push、splice 或其中某项的 name 被修改时,ranks_options 将自动重新求值并触发视图更新。
立即学习“前端免费学习笔记(深入)”;
⚠️ 注意事项:
- 若 form.ranks 中存在 null 或 undefined 的 name,ranks_options 将包含对应空值;建议根据业务需要添加安全访问(如 item?.name ?? '');
- computed 返回的是只读代理(Readonly),不可直接赋值;如需可写逻辑,请配合 computed({ get, set }) 语法;
- 避免在 computed 内部执行副作用(如 API 调用、DOM 操作),保持其纯函数特性。
? 总结:在 Composition API 中,所有依赖响应式源的派生状态,都应通过 computed 显式声明——这是 Vue 响应式系统正确建立依赖关系的唯一可靠方式。切勿将响应式对象的属性访问或方法调用结果直接赋给普通变量,否则将主动切断响应式链路。










