Vue3.0响应式原理
Vue3.0的响应式基于Proxy实现。具体代码如下:
1 let targetMap = new WeakMap()
2 let effectStack = [] //存储副作用
3
4 const track = (target, key) => {
5 let effect = effectStack[effectStack.length -1]
6 if(effect){
7 //收集依赖
8 let depMap = targetMap.get(target)
9 if(depMap === undefined){
10 depMap = new Map()
11 targetMap.set(target,depMap) //effect dep 集合
12 }
13
14 let dep = depMap.get(key)
15 if(dep === undefined){
16 dep = new Set() //存储effect
17 depMap.set(key,dep)
18 }
19
20 if(!dep.has(effect)){
21 dep.add(effect)
22 effect.deps.push(dep)
23 }
24 }
25 }
26
27 const trigger = (target,key) => {
28 let depMap = targetMap.get(target)
29 if(depMap === undefined){
30 return //没有副作用
31 }
32
33 const effects = new Set()
34 const computeds = new Set()
35
36 if(key){
37 let deps = depMap.get(key)
38 deps.forEach(effect => {
39 if(effect.computed){
40 computeds.add(effect)
41 } else {
42 effects.add(effect)
43 }
44 })
45 }
46
47 effects.forEach(effect => effect())
48 computeds.forEach(computed => computed)
49 }
50
51 const handler = {
52 get(target,key,receiver){
53 track(target,key) //依赖收集
54 let ret = Reflect.get(...arguments)
55 return typeof ret == 'object' ? reactive(ret) : ret
56 },
57 set(target,key,value,receiver){
58 let info = Reflect.set(...arguments)
59 trigger(target,key) //执行副作用
60 }
61 }
62
63 const reactive = (target) => {
64 let observe = new Proxy(target,handler)
65 return observe
66 }
67
68 const effect = (fn, options={}) => {
69 let e = crateRectiveEffect(fn,options)
70 if(!options.lazy){
71 e()
72 }
73 return e
74 }
75
76 const crateRectiveEffect = (fn, options) => {
77 const effect = (...args) => {
78 return run(effect, fn, args)
79 }
80 effect.deps = []
81 effect.computed = options.computed
82 effect.lazy = options.lazy
83 return effect
84 }
85
86 //收集副作用 执行函数
87 const run = (effect, fn, args) => {
88 console.log(fn);
89 if(!effectStack.includes(effect)){
90 try{
91 effectStack.push(effect)
92 return fn(...args)
93 } finally {
94 effectStack.pop()
95 }
96 }
97 }
98
99 const computed = (fn) => {
100 const runner = effect(fn,{computed:true,lazy:true})
101 return {
102 // effect: runner,
103 get value() {
104 return runner()
105 }
106 }
107 }
调用:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>响应式</title>
<script src="main.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app"></div>
<button id="btn">click </button> <script type="text/javascript">
const root = document.getElementById('app')
const btn = document.getElementById('btn') const o = {
name:'terry',
age:1
}
let objj = reactive(o)
let double = computed(()=> objj.age*2)
effect(()=>{
root.innerHTML = `
<h1>${objj.name}今年${objj.age}岁了, ${double.value}</h1>
`
})
btn.addEventListener('click',()=>{
objj.age+=1
},false)
</script>
</body>
</html>
Vue3.0响应式原理的更多相关文章
- Vue3.0工程创建 && setup、ref、reactive函数 && Vue3.0响应式实现原理
1 # 一.创建Vue3.0工程 2 # 1.使用vue-cli创建 3 # 官方文档: https://cli.vuejs.org/zh/guide/creating-a-project.html# ...
- vue2.0与3.0响应式原理机制
vue2.0响应式原理 - defineProperty 这个原理老生常谈了,就是拦截对象,给对象的属性增加set 和 get方法,因为核心是defineProperty所以还需要对数组的方法进行拦截 ...
- Vue 2.0 与 Vue 3.0 响应式原理比较
Vue 2.0 的响应式是基于Object.defineProperty实现的 当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的 prop ...
- Vue3.0 响应式数据原理:ES6 Proxy
Vue3.0 开始用 Proxy 代替 Object.defineProperty了,这篇文章结合实例教你如何使用Proxy 本篇文章同时收录[前端知识点]中,链接直达 阅读本文您将收获 JavaSc ...
- Vue3.0响应式实现
基于Proxy // 弱引用映射表 es6 防止对象不能被回收 let toProxy = new WeakMap(); // 原对象: 代理过得对象 let toRaw = new WeakMap( ...
- Vue2.0响应式原理以及重写数组方法
// 重写数组方法 let oldArrayPrototype = Array.prototype; let proto = Object.create(oldArrayPrototype); ['p ...
- vue2与vue3实现响应式的原理区别和提升
区别: vue2.x: 实现原理: 对象类型:Object.defineProperty()对属性的读取,修改进行拦截(数据劫持): 数组类型:通过重写更新数组的一系列方法来进行拦截(对数组的变更方法 ...
- vue3剖析:响应式原理——effect
响应式原理 源码目录:https://github.com/vuejs/vue-next/tree/master/packages/reactivity 模块 ref: reactive: compu ...
- 由浅入深,带你用JavaScript实现响应式原理(Vue2、Vue3响应式原理)
由浅入深,带你用JavaScript实现响应式原理 前言 为什么前端框架Vue能够做到响应式?当依赖数据发生变化时,会对页面进行自动更新,其原理还是在于对响应式数据的获取和设置进行了监听,一旦监听到数 ...
随机推荐
- sessionFactory' defined in class path /mappingDirectoryLocations配置问题
问题:配置好aplicationContext.xml,启动tomcat 出现如下问题 sessionFactory无法正常建立 Context initialization failed org.s ...
- 多测师讲解自动化测试 _RF封装_(三层模式)高级讲师肖sir
rf自动化:分层作用: 1.项目----有重复的流程(借款-登录,出借-登录) 2.借款--登录(8个流程)机器人:案例层(用例)写在机器人中,1个机器人=1条用例 分三个层次: 1.案例层(存放用例 ...
- 2019年CSP-J初赛试题(普及组)试题详解
https://www.jianshu.com/p/9e58f455c1ee https://blog.csdn.net/weixin_39104847/article/details/1086711 ...
- day30 Pyhton 面向对象 反射
@property # 例1 - 1 (某一个属性如果是通过计算得来的,那么计算的过程写在方法里,把这个方法伪装成属性) from math import pi # class Circle: # d ...
- BUUCTF-misc九连环 详解
这个没什么玄学,我们解压出来一张照片,放到hxd中搂一眼,最后结尾的那几行中看到了zip压缩包的结尾标识符,难道这里面还有压缩包,于是我们就formostlrb 果然有图片有压缩包 我们打开压缩包看到 ...
- Redis 字典结构细谈
Redis 字典底层基于哈希表实现. 一.哈希表结构 1.dictht: typedef struct dictht { dictEntry **table; //哈希表数组,存储具体的键值对元素,对 ...
- linux学习(二)--setup.s
执行过bootsect.s,加载了所有系统代码之后,开始向32位模式转变,为main函数的调用做准备,同样,附上图往下看 1 INITSEG = 0x9000 ! we move boot here ...
- centos8平台使用ip命令代替ifconfig管理网络
一,为什么建议使用ip命令代替ifconfig? 1,ifconfig所属的net-tools包已经不再被维护了 虽然可以用,但会发生看不到部分ip等情况, [root@centos8 liuhong ...
- 通透,23 个问题 TCP 疑难杂症全解析
每个时代,都不会亏待会学习的人. 在进入今天主题之前我先抛几个问题,这篇文章一共提出 23 个问题. TCP 握手一定是三次?TCP 挥手一定是四次? 为什么要有快速重传,超时重传不够用?为什么要有 ...
- PHPStorm注释缩进问题
以下是让强迫症很难受的注释格式 以下几步即可解决强迫症的烦恼 1.点击File 2.点击setting 3.按照以下几步走 4.按照以下几步走 5.最后效果如下