0

0

一文详解Vue中响应式原理

青灯夜游

青灯夜游

发布时间:2023-02-13 19:30:59

|

1907人浏览过

|

来源于掘金社区

转载

本篇文章带大家学习vue,深入了解vue中响应式原理,希望对大家有所帮助!

一文详解Vue中响应式原理

以此文纪念将要逝去的响应式语法糖

废话不多说,直接进入正题,响应式在日常开发中的应用是很常见的,这里举个简单的例子:

let a=3
let b=a*10
console.log(b)//30
a=4
console.log(b)//40

这时候我们想让b=4*10,这样显然是不行的,即使我们在前面加上个var也只会发生变量提升,我们所给的值并不会提升。

而这个时候,响应式的作用就体现出来了:

立即学习前端免费学习笔记(深入)”;

import { reactive } from 'vue'

let state = reactive({ a: 3 })
let b = computed(() => state.a * 10)
console.log(b.value) // 30
state.a = 4
console.log(b.value) // 40

只需要一个简单的响应式API便可实现跟踪变化的效果。【相关推荐:vuejs视频教程web前端开发

分析一下reactive

事实上,Vue3的reactive的本质上就是一个发布订阅模式

通过创建依赖图来跟踪数据的依赖关系。依赖图是一个图形,它描述了哪些数据是依赖于哪些数据的。当数据发生变化时,Vue 3 的 reactive 系统会自动触发视图的更新。这是因为它在依赖图中跟踪了数据变化,并通过将其与视图的更新关联起来来实现的

这里我列出尤大在Vue Master里演示的代码做个简单的示例:

class Dep{
    constructor(value){
        this.subscribers=new Set()
        this._value=value
    }
    get value(){
        this.depend()
        return this._value
    }
    set value(newValue){
        this._value=newValue
        this.notify()
    }
    depend(){
        if(activeEffect){
            this.subscribers.add(activeEffect)
        }
    }
    notify(){
        this.subscribers.forEach(effect=>{
            effect()
        })
    }
}

我们来分析一下这段代码:

  • 定义一个subscribe属性,作为一个订阅者列表,用来存储所有的订阅者信息
  • depend函数用来管理依赖关系,即该订阅者所依赖的该变量
  • notify函数便是作为通知所有订阅者该变量的值已经发生变化

当变量的值发生变化的时候,它便可以自动的通知所有的订阅者进行更新了

Vue2的Object.defineProperty

事实上,在Vue2时期,响应式的都是交给Object.defineProperty来实现的,但在Vue3当中切换成了Proxy,我们等下来结合实际代码来看原因;我们先来看看Vue2是如何实现的:

SuperCms在线订餐系统
SuperCms在线订餐系统

模板采用响应式设计,自动适应手机,电脑及平板显示;满足单一店铺外卖需求。功能:1.菜单分类管理2.菜品管理:菜品增加,删除,修改3.订单管理4.友情链接管理5.数据库备份6.文章模块:如:促销活动,帮助中心7.单页模块:如:企业信息,关于我们更强大的功能在开发中……安装方法:上传到网站根目录,运行http://www.***.com/install 自动

下载
function reactive(raw){
    Object.keys(raw).forEach(ket=>{
        const dep=new Dep()
        let value=raw[key]
        
        Object.definProperty(raw,key,{
            get(){
                dep.depend()
                return value
            },
            //当属性发生
            set(newValue){
                value=newValue
                dep.notify()
            }
        })
    })
    //这时候返回的原始对象已经具有响应性
    return raw
}

这样一个简单的响应式API就实现了

但这里缺点也就很明显了:在 Vue 2.x 中,被传入的对象会直接被 Vue.observable 变更 而在Vue3当中,则是会返回一个可响应的代理,而对源对象直接进行变更仍然是不可响应的

这就导致了:

  • 当我们添加或者删除对象的属性时,Vue2的响应式是无法检测的,由于 Vue 会在初始化实例时对 property 执行 getter/setter 转化,所以 property 必须在 data 对象上存在才能让 Vue 将它转换为响应式的
  • 无法检测数组下标和长度的变化

当然,这个属于历史局限了,当时ES5也就只能选择Object.definProperty,但在了ES6版本,便多了Proxy,这时候Vue的响应式便得到了升级

Vue3的Proxy

Vue3采用Proxy来监控数据的变化,相较于Vue2来说,不仅解决了上述的问题,还有这些优势:

  • 无需再使用vue.$set来触发响应式,这让代码看上去能过更加简介
  • 全方位的数组变化检测,消除Vue2中无效边界情况
  • 减少了Vue3中书写响应式的代码量,这让我们的开发更加方便

让我们来看看实际代码是什么样子的:

const reactiveHandles={
    get(target,key,receiver){
        const dep=getDep(target,key)
        dep.depend()
        return Reflect.get(target,key,receiver)
    },
    set(target,key,value,receiver){
        const dep=getDep(target,key)
        const result=Reflect.set(target,key,value,receiver)
        dep.notify()
        return result
    }
}

通过对对象进行收集依赖来实现响应式的方式也便是Vue3响应式的精髓

ref

在官方文档有句话:reactive() 的种种限制归根结底是因为 JavaScript 没有可以作用于所有值类型的 “引用” 机制,而reactive的限制便是:

  • 只能处理可被观测的数据结构,如数组和对象;而不可观测的数据结构,如原始数据类型就无法被其监测
  • 只能处理定义在它所在组件的数据,不能处理全局变量

而这个时候就需要ref来登场了,ref便是针对基本数据类型而诞生的,弥补了reactive的缺陷,简单的来说,ref更加适合简单的单个可变值(不过实际开发大多数时候都是ref一把梭哈哈哈

这里顺便提一下,响应式语法糖的提案被取消了还是蛮可惜的

(学习视频分享:vuejs入门教程编程基础视频

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
java入门学习合集
java入门学习合集

本专题整合了java入门学习指南、初学者项目实战、入门到精通等等内容,阅读专题下面的文章了解更多详细学习方法。

2

2026.01.29

java配置环境变量教程合集
java配置环境变量教程合集

本专题整合了java配置环境变量设置、步骤、安装jdk、避免冲突等等相关内容,阅读专题下面的文章了解更多详细操作。

2

2026.01.29

java成品学习网站推荐大全
java成品学习网站推荐大全

本专题整合了java成品网站、在线成品网站源码、源码入口等等相关内容,阅读专题下面的文章了解更多详细推荐内容。

0

2026.01.29

Java字符串处理使用教程合集
Java字符串处理使用教程合集

本专题整合了Java字符串截取、处理、使用、实战等等教程内容,阅读专题下面的文章了解详细操作教程。

0

2026.01.29

Java空对象相关教程合集
Java空对象相关教程合集

本专题整合了Java空对象相关教程,阅读专题下面的文章了解更多详细内容。

3

2026.01.29

clawdbot ai使用教程 保姆级clawdbot部署安装手册
clawdbot ai使用教程 保姆级clawdbot部署安装手册

Clawdbot是一个“有灵魂”的AI助手,可以帮用户清空收件箱、发送电子邮件、管理日历、办理航班值机等等,并且可以接入用户常用的任何聊天APP,所有的操作均可通过WhatsApp、Telegram等平台完成,用户只需通过对话,就能操控设备自动执行各类任务。

25

2026.01.29

clawdbot龙虾机器人官网入口 clawdbot ai官方网站地址
clawdbot龙虾机器人官网入口 clawdbot ai官方网站地址

clawdbot龙虾机器人官网入口:https://clawd.bot/,clawdbot ai是一个“有灵魂”的AI助手,可以帮用户清空收件箱、发送电子邮件、管理日历、办理航班值机等等,并且可以接入用户常用的任何聊天APP,所有的操作均可通过WhatsApp、Telegram等平台完成,用户只需通过对话,就能操控设备自动执行各类任务。

16

2026.01.29

Golang 网络安全与加密实战
Golang 网络安全与加密实战

本专题系统讲解 Golang 在网络安全与加密技术中的应用,包括对称加密与非对称加密(AES、RSA)、哈希与数字签名、JWT身份认证、SSL/TLS 安全通信、常见网络攻击防范(如SQL注入、XSS、CSRF)及其防护措施。通过实战案例,帮助学习者掌握 如何使用 Go 语言保障网络通信的安全性,保护用户数据与隐私。

8

2026.01.29

俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

622

2026.01.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Node.js 教程
Node.js 教程

共57课时 | 9.7万人学习

CSS3 教程
CSS3 教程

共18课时 | 5万人学习

Vue 教程
Vue 教程

共42课时 | 7.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号