Vue3 指令体系与响应式进阶
本页关键词:v-if、v-show、v-on、v-bind、v-model、toRaw、markRaw、customRef、Vue2→Vue3
一、Vue 指令体系(v- 是什么 & 常见指令用法)
什么是 v-?
v- 是 Vue 提供的模板指令前缀,本质是:在模板中声明式地告诉 Vue,这个 DOM 如何与 JS 数据产生关系。Vue 会把 v- 指令编译成底层的 DOM 操作代码。
text
v-指令 = Vue 帮你写好的 DOM 操作语法糖v-if / v-show(控制 DOM 显隐)
v-if:控制 DOM 的「创建 / 销毁」
vue
<p v-if="isLogin">欢迎你</p>- 条件为
false→ DOM 不存在 - 切换时触发生命周期(创建 / 卸载)
- 性能成本高,适合低频切换
v-show:控制 CSS 显示隐藏
vue
<p v-show="isLogin">欢迎你</p>- DOM 始终存在
- 只改
display - 高频切换首选
面试要点:v-if 控制 DOM 存否,切换成本高;v-show 始终保留 DOM,仅改 display,适合频繁切换。
v-on(事件绑定)
vue
<button v-on:click="add">+</button>
<!-- 简写 -->
<button @click="add">+</button>v-bind(属性绑定)
vue
<img v-bind:src="imgUrl" />
<!-- 简写 -->
<img :src="imgUrl" />Vue 内部根据属性类型,智能选择 property / attribute,而非单纯使用 setAttribute。
v-model(双向绑定)
最基础用法(输入框)
vue
<input v-model="username" />
<p>{{ username }}</p>本质: v-model = v-bind:value + v-on:input 的语法糖
表单控件
复选框: agree 为 true / false
单选框: gender 为 'male' 或 'female'
v-if 和 v-show 的核心区别是什么?
v-if 控制 DOM 的创建和销毁,切换成本高但初始性能好; v-show 始终保留 DOM,仅通过 display 控制显示,适合频繁切换。
v-model 的底层本质是什么?
v-model 是 v-bind:value + v-on:input 的语法糖,实现数据与视图的双向同步。
二、Vue3 响应式进阶:toRaw / markRaw / customRef
toRaw(拿回原始对象)
js
import { reactive, toRaw } from 'vue'
const obj = reactive({ count: 0 })
const raw = toRaw(obj)- 从 Proxy 中取出原始对象
- 用于调试 / 传给第三方库
- 不要用 raw 去修改数据
markRaw(让对象不被响应式处理)
js
import { markRaw } from 'vue'
const map = markRaw(new Map())- 第三方实例(ECharts、Map、播放器)
- 大对象,不需要响应式
customRef(自定义响应式行为)
场景:防抖输入
js
import { customRef } from 'vue'
function useDebouncedRef(value, delay = 500) {
let timer
return customRef((track, trigger) => ({
get() {
track()
return value
},
set(newValue) {
clearTimeout(timer)
timer = setTimeout(() => {
value = newValue
trigger()
}, delay)
}
}))
}
const keyword = useDebouncedRef('')面试要点:customRef 可把防抖、节流等逻辑注入 Vue 响应式系统。
防抖 vs 节流
| 类型 | 核心思想 | 例子 |
|---|---|---|
| 防抖 | 停下来才执行 | 搜索框 |
| 节流 | 一段时间执行一次 | 滚动监听 |
markRaw 和 toRaw 的区别?
markRaw 是“从一开始就不做响应式”; toRaw 是“已经响应式了,再拿回原始对象”。
customRef 的核心价值是什么?
允许开发者自定义 get/set 行为,把防抖、节流等逻辑注入 Vue 响应式系统。
三、Vue2 → Vue3 必须知道的变化
全局 API 改变
Vue2:
js
Vue.component()
Vue.use()
Vue.mixin()Vue3:
js
const app = createApp(App)
app.component()
app.use()
app.mixin()
app.mount('#app')所有全局能力都挂在 app 上,避免全局污染,支持多应用并存。
响应式系统升级
| Vue2 | Vue3 |
|---|---|
| Object.defineProperty | Proxy |
| 无法监听新增属性 | 完美支持 |
| 数组 hack | 原生支持 |
v-model 改动
- Vue3 默认
modelValue - 可多个 v-model
vue
<MyComp v-model:title="title" />生命周期变化
| Vue2 | Vue3 |
|---|---|
| beforeDestroy | beforeUnmount |
| destroyed | unmounted |
为什么 Vue3 不再直接用 Vue.component?
Vue3 使用 createApp 创建应用实例,避免全局污染,支持多应用并存。
Vue3 响应式为什么更强?
基于 Proxy,可拦截所有操作,支持新增属性、删除属性和数组变化。