网站首页 > 教程文章 正文
Vue 中的 $set 方法(Vue.set)主要用于 向响应式对象中添加一个新的属性,并确保这个新属性是响应式的,能够触发视图更新。
背景问题:为什么需要 $set?
在 Vue 2 中,直接给对象新增属性不会触发视图更新,例如:
this.obj.a = 123 // 如果 a 原本不存在,则不会触发视图更新
这是因为 Vue 2 是基于 Object.defineProperty 来实现响应式系统的,它在对象初始化时只能“劫持”已有属性,无法监控新增的属性。
$set 的作用
this.$set(obj, key, value)
或者
Vue.set(obj, key, value)
它的作用是:
- 为对象添加新属性
- 让这个新属性是响应式的
- 触发视图更新
原理解析(Vue 2)
Vue.set = function (target, key, val) {
if (Array.isArray(target) && isValidIndex(key)) {
// 对数组使用 splice 替代设置
target.splice(key, 1, val)
return val
}
if (key in target && !(key in Object.prototype)) {
target[key] = val
return val
}
const ob = target.__ob__ // 这是 Observer 实例
if (!ob) {
target[key] = val
return val
}
defineReactive(ob.value, key, val) // 核心:为新属性定义响应式
ob.dep.notify() // 通知依赖更新
return val
}
核心步骤:
- 判断是否是数组:数组用 splice 替代赋值(因为 Vue 对数组的监听基于方法拦截)。
- 通过 defineReactive() 为新属性添加 getter/setter,注入依赖收集逻辑。
- 通知依赖更新视图(dep.notify())
示例
<template>
<div>{{ user.name }}</div>
<button @click="addProp">添加新属性</button>
</template>
<script>
export default {
data() {
return {
user: {}
}
},
methods: {
addProp() {
this.$set(this.user, 'name', '张三') // 触发视图更新
}
}
}
</script>
Vue 3 呢?
在 Vue 3 中,由于使用了 Proxy 实现响应式,不需要 $set 了,你可以直接赋值:
reactiveObj.newKey = 123 // 直接响应式,无需 $set
总结
项目 | Vue 2 | Vue 3 |
添加响应式属性 | 需要 $set | 不需要,直接赋值即可 |
实现机制 | Object.defineProperty + defineReactive | Proxy 拦截所有操作 |
数组监听 | 依赖重写 push/splice 等方法 | Proxy 完整拦截 |
需要我帮你用简单代码实现一个简化版的 $set 吗?可以更好理解它的内部逻辑。
猜你喜欢
- 2025-05-23 JavaScript巩固基础每日随记之[数组]
- 2025-05-23 你应该掌握的 10 种 JavaScript 对象处理技巧
- 2025-05-23 更简单的Vue3中后台动态路由 + 侧边栏渲染方案
- 2025-05-23 2023:Js中新增四个不修改原数组的方法
- 2025-05-23 常见vue面试题,大厂小厂都一样
- 2025-05-23 在vue实现element ui中的card(卡片中)使用多选和分页
- 2025-05-23 js数组常用方法总结
- 2025-05-23 php手把手教你做网站(三十八)jquery 转轮盘抽奖,开盲盒
- 2025-05-23 关于数组的操作方法
- 2025-05-23 javascript基础入门
- 05-25干货 | 一步步部署 Flask 应用
- 05-25别再去找Docker命令了,你要的常用的全都在这
- 05-25如果您删除Windows11上的“Program Files”文件夹会发生什么?
- 05-25家用nas最常用的docker容器及部署方法
- 05-25你好 dotnet run file, 再见 csproj
- 05-25China committed to continuing contributions to global health: delegation
- 05-25Chinese, German experts urge cooperation during Eurasia relations seminar
- 05-25Peace of paramount importance for region
- 最近发表
-
- 干货 | 一步步部署 Flask 应用
- 别再去找Docker命令了,你要的常用的全都在这
- 如果您删除Windows11上的“Program Files”文件夹会发生什么?
- 家用nas最常用的docker容器及部署方法
- 你好 dotnet run file, 再见 csproj
- China committed to continuing contributions to global health: delegation
- Chinese, German experts urge cooperation during Eurasia relations seminar
- Peace of paramount importance for region
- after和in用法解析
- China's top diplomat to chair third China-Pacific Island countries foreign ministers' meeting
- 标签列表
-
- location.href (44)
- document.ready (36)
- git checkout -b (34)
- 跃点数 (35)
- 阿里云镜像地址 (33)
- qt qmessagebox (36)
- mybatis plus page (35)
- vue @scroll (38)
- 堆栈区别 (33)
- 什么是容器 (33)
- sha1 md5 (33)
- navicat导出数据 (34)
- 阿里云acp考试 (33)
- 阿里云 nacos (34)
- redhat官网下载镜像 (36)
- srs服务器 (33)
- pico开发者 (33)
- https的端口号 (34)
- vscode更改主题 (35)
- 阿里云资源池 (34)
- os.path.join (33)
- redis aof rdb 区别 (33)
- 302跳转 (33)
- http method (35)
- js array splice (33)