Vue响应式系统要求数据必须被ref或reactive显式包裹才能触发更新;直接修改普通对象属性无效,v-model、computed和watch均依赖此机制。

Vue 不是框架“概念”,而是响应式系统驱动的视图层工具——它不强制你写组件,但一旦你用 ref 或 reactive 声明数据,后续所有 DOM 更新就自动跟上了。
为什么直接改对象属性没反应?data 必须被 Vue “接管”
常见错误:在 setup() 里写 let user = { name: 'Alice' },再执行 user.name = 'Bob',界面不动。因为普通对象没有 getter/setter,Vue 捕捉不到变化。
正确做法是用响应式 API 包裹:
-
ref()适合基础类型(string、number、boolean)和需要解构的场景,访问时必须加.value -
reactive()适合对象/数组,语法更自然,但不能解构(会丢失响应性) - 深层嵌套对象也自动响应,无需手动
ref每一层
import { ref, reactive } from 'vue'
// ✅ 正确:ref 包裹基础值
const count = ref(0)
count.value++ // 触发更新
// ✅ 正确:reactive 包裹对象
const state = reactive({ name: 'Alice', items: [] })
state.name = 'Bob' // 直接赋值,响应生效
state.items.push('new item') // 数组变更也响应
v-model 不是语法糖,它是响应式系统的“快捷入口”
很多人以为 v-model 只是 v-bind:value + v-on:input 的简写,其实它底层依赖的是 ref 或 reactive 返回的响应式对象。如果绑定的不是响应式数据,v-model 就完全失效。
立即学习“Java免费学习笔记(深入)”;
技术上面应用了三层结构,AJAX框架,URL重写等基础的开发。并用了动软的代码生成器及数据访问类,加进了一些自己用到的小功能,算是整理了一些自己的操作类。系统设计上面说不出用什么模式,大体设计是后台分两级分类,设置好一级之后,再设置二级并选择栏目类型,如内容,列表,上传文件,新窗口等。这样就可以生成无限多个二级分类,也就是网站栏目。对于扩展性来说,如果有新的需求可以直接加一个栏目类型并新加功能操作
使用要点:
- 绑定
ref:直接写v-model="searchText",searchText必须是ref()创建的 - 绑定
reactive对象字段:写v-model="form.email",form是reactive({ email: '' }) - 自定义组件要支持
v-model,需显式声明modelValueprop 并触发update:modelValue事件
计算属性 computed 和监听器 watch 怎么选?
两者都依赖响应式系统,但触发时机和用途完全不同:
-
computed是“惰性求值”:只在被模板或其它computed读取时才执行,且有缓存;适合派生状态,比如fullName由firstName和lastName组合 -
watch是“副作用驱动”:响应式数据一变就立刻执行回调,适合发起请求、操作 DOM、修改非响应式第三方库状态 - 监听
ref直接传变量;监听reactive对象建议用函数返回要监听的字段(避免误触发)
import { ref, reactive, computed, watch } from 'vue'
const search = ref('')
const list = ref([])
// ✅ computed:过滤列表,仅当 search 或 list 变化时重新计算
const filteredList = computed(() => list.value.filter(i => i.includes(search.value)))
// ✅ watch:搜索关键词变了就发请求
watch(search, (newVal) => {
if (newVal) fetch(`/api/search?q=${newVal}`)
})
响应式系统不是魔法,它的边界很清晰:只追踪你在 setup() 中明确用 ref/reactive 创建的数据。任何从外部赋值进来的普通对象、函数返回的对象、JSON.parse() 的结果,都不会自动响应——该包就得包,该转就得转。










