玩转 Vue 3 全家桶
大圣
前百度前端架构师
38321 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 44 讲
玩转 Vue 3 全家桶
15
15
1.0x
00:00/00:00
登录|注册

07 | 巧妙的响应式:深入理解Vue 3的响应式机制

使用useFullscreen
安装VueUse
例子:利用get和set函数实现响应式
Proxy相对于defineProperty的优势
例子:使用Proxy实现响应式
defineProperty的缺陷
例子:使用defineProperty实现响应式
思考题
VueUse工具包的介绍
响应式机制的进阶用法
响应式的概念和必要性
使用VueUse工具包
抽离useStorage函数
watchEffect的使用
对象的get和set函数
Vue 3的Proxy
Vue 2的defineProperty
通过函数封装实现响应式
JavaScript变量的特点
总结
定制响应式数据
响应式原理
什么是响应式
响应式机制

该思维导图由 AI 生成,仅供参考

你好,我是大圣。在上一讲中,我给你介绍了 Composition API 相比于 Option API 的优点,以及 <script setup> 的语法,这些内容能够给我们后面的开发打下了坚实的基础。
今天我带你深入了解一下 Vue 3 的响应式机制,相信学完今天的内容,你会对响应式机制有更深地体会。我还会结合代码示例,帮你掌握响应式机制的进阶用法,让我们正式开始学习吧!

什么是响应式

响应式一直都是 Vue 的特色功能之一。与之相比,JavaScript 里面的变量,是没有响应式这个概念的。你在学习 JavaScript 的时候首先被灌输的概念,就是代码是自上而下执行的。我们看下面的代码,代码在执行后,打印输出的两次 double 的结果也都是 2。即使我们修改了代码中的 count 的值后,double 的值也不会有任何改变。
let count = 1
let double = count * 2
console.log(double)
count = 2
console.log(double)
double 的值是根据 count 的值乘以二计算而得到的,如果现在我们想让 doube 能够跟着 count 的变化而变化,那么我们就需要在每次 count 的值修改后,重新计算 double。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Vue 3的响应式机制是本文的重点。文章首先介绍了响应式的概念和原理,通过比较JavaScript中普通变量和响应式变量的区别,引出了响应式的需求。在介绍响应式原理时,作者分别讲解了Vue 2中使用defineProperty实现响应式的方法以及其存在的缺陷,然后详细介绍了Vue 3中基于Proxy实现响应式的方式,并指出了Proxy相对于defineProperty的优势。此外,文章还提到了Vue 3中利用对象的get和set函数来进行监听的响应式实现方式,以及reactive和ref这两个API的使用方法。进一步,文章介绍了如何在Vue内部进阶地使用响应式机制,去封装独立的函数,以及如何使用VueUse工具包来提高开发效率。总的来说,本文深入浅出地介绍了Vue 3的响应式机制,对于想深入理解Vue 3的读者来说,是一篇值得阅读的文章。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《玩转 Vue 3 全家桶》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(46)

  • 最新
  • 精选
  • ll
    1. 为什么需要响应式? 随着页面应用的不断复杂,需要关注和管理的状态越来越多,之前靠被动的,分散的管 理状态不现实也易出错。为了满足这个需求,出现了许多方案,其中 Vue 提出的或主打 的解决方案的就是响应式。 2. 怎么实现响应式? 响应式主要解决的问题是怎么让在“语言层面上分散的独立数据”在“业务层面”上产生“联 系或互为因果”的关系。这咋么办呢?怎么产生“联系”呢?简单,“你发生变化的时候告 诉我一声,我应声而动”,所谓响应式我个人理解就是“你响我应”。 但是这种需求在语言上不是“普遍需求”,属于“特殊需求”,怎么解决?这里就引入了“代 理模式”这种设计模式。在语言层面我给你一种模式可以满足你的需求,ES5 的时代,是 defineProperty 等,ES6 就是 Proxy。 至于 ES6 的 Proxy 在性能或是各方面要优于 defineProperty 还是因为 Proxy 在更底 层优化或重新实现,使用的表现“一样”,但“地基”不一样,性能各方面自然是不一样。 正因为是“地基”的不同,Proxy 就还存在兼容性的问题, 加上业务场景的不同, defineProperty 还是有应用的场景,至于文中说的 Vue 3 的 ref 是用 “getter setter” 实现的,我的认识是,一个是“初始化”时的行为,一个是“改变行为”。 3. useXXX 为什么会这么灵活? 像之前的 Composition API 我理解的是 Vue 的组织单位由 “组件” 变成 “数据” 了, 现在组件在引入 useXXX,关注点在 XXX,至于 XXX 跟什么有联系,那是你的事情,在 你自己的 useXXX 里去实现。 本节提到的 React Hooks 也有异曲同工的意思,Hooks 直接翻译成什么?“钩子”,用来 做什么?“钩东西”,钩什么?那先说下这个东西出来之前有什么。 React Hooks 出来之前 React 主要构建 App 还是用 Class Component,当然也有 functional component,这俩区别就在于 class 有状态,functional 比较“纯粹”没有 状态。这样复用成问题,得用什么高阶组件之类的方式。然后,在某一时刻,同样的问 题出现了,React 复用组件的也是以带状态的 Class 组件为主,“复杂”了,不纯粹。 应用越大,这种模式开发或维护越复杂。然后 Hooks 出现了,现在 React 都用 “functional” 组件,但是有“状态”的,状态哪里来的 “Hook” 过来的,钩过来的。 组件“不负责”维护状态,useXXX 去管理了。 综上,灵活了,也好维护了

    作者回复: 总结的太棒了!

    2021-11-01
    7
    121
  • Warn
    useStorage函数中,ref初始赋值时应该是使用参数value代替'[]'不? ``` function useStorage(name, value=[]){ let data = ref(JSON.parse(localStorage.getItem(name)) || value) ...code } ```

    作者回复: 对对对 囧 写出bug了没注意

    2021-11-01
    7
    7
  • ps Sensking
    请问是watch watcheffect 那个性能高呀?有人说过watch性能能好一点

    作者回复: 理论上watcheffect会好一些,watcheffect做了任务队列的更新和收集

    2021-11-01
    2
    7
  • Geek_fcdf7b
    大圣老师,请教一下,3.2版本之后,是不是定义响应式数据都可以用ref一把梭?我看有的文章是这样说的,ref在3.2之后性能进行了大幅度提升,所以建议使用ref,不管简单数据还是复杂数据都可以用ref,没必要用reactive

    作者回复: 现在ref确实是比reactive优先级更高一些,直接建议ref + toRefs一把梭,我碰到必须有reactive的场景的话会写个加餐对比,而且ref能够支持复杂的数据结构,也是调用了reactive

    2021-12-09
    6
  • 风一样
    link[rel*="icon"] 老师请问这个是过滤什么呢?

    作者回复: 这是一个css选择器,过滤标签有rel属性的值中,包含icon的标签

    2021-11-11
    2
    3
  • 奔跑的小乌龟
    浏览器页面全屏、滚动等的封装,之前有需求就是全屏要动态调整页面的布局,在没有封装的情况下,就要每个页面需要时都写监听,而用useXXX感觉会优雅很多啊,点赞,学到了,赶紧实践实践。

    作者回复: 很棒的心得

    2021-11-02
    2
    3
  • 碎竹落棋
    想问一下,问啥vscode里,ctrl+左键不能跳转到函数定义,我创建的这个vue3项目里都跳转不了,拿以前写的vue2项目试了一下,可以跳转,好奇怪

    作者回复: 你换成volar插件试试?

    2021-11-12
    2
  • 笑叹尘世
    第一次加到存储里todos:[{"title":"2222","done":false}]。 刷新页面后存储里的tods变成了"[{\"title\":\"2222\",\"done\":false}]"

    作者回复: storage数据取出来之前记得用JSON.parse和JSON.stringify处理一下

    2021-11-09
    2
    2
  • Estelle
    你好 我想问下 let proxy = new Proxy(obj,{ get : function (target,prop) { return target[prop] }, set : function (target,prop,value) { target[prop] = value; if(prop==='count'){ double = getDouble(value) } }, deleteProperty(target,prop){ delete target[prop] if(prop==='count'){ double = NaN } } }) console.log(obj.count,double) proxy.count = 2 console.log(obj.count,double) delete proxy.count // 删除属性后,我们打印log时,输出的结果就会是 undefined NaN console.log(obj.count,double) 执行这个时候 控制台报错:TypeError: 'set' on proxy: trap returned falsish for property 'count'。 是什么原因 希望能解答

    作者回复: 能贴一下全部的代码妈?我本地按照你的代码三个console.log的结果如下, 并且没有报错 undefined 2 2 4 undefined NaN

    2021-11-05
    4
    2
  • nabaonan
    希望更加深入讲一下,vue3的响应式原理,是如何进行依赖收集的,并触发响应到数据的,串一下流程,还有为什么用watchEffect而不用watch,都适用于哪些场景,各有什么优势

    作者回复: 这个在最后的手写代码章节有介绍的

    2021-11-04
    2
    2
收起评论
显示
设置
留言
46
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部