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能够做到响应式?当依赖数据发生变化时,会对页面进行自动更新,其原理还是在于对响应式数据的获取和设置进行了监听,一旦监听到数 ...
随机推荐
- rxjs入门4之rxjs模式设计
观察者模式 (Observer Pattern) 观察者模式其实在日常编码中经常遇到,比如DOM的事件监听,代码如下 function clickHandler(event) { console.lo ...
- vs code 编译python 输出到调试控制台
如图所示,在debug菜单中点击齿轮按钮,进入launch.json,更改console选项的值(有三种) "console": "internalConsole&quo ...
- go-zero 如何应对海量定时/延迟任务?
一个系统中存在着大量的调度任务,同时调度任务存在时间的滞后性,而大量的调度任务如果每一个都使用自己的调度器来管理任务的生命周期的话,浪费cpu的资源而且很低效. 本文来介绍 go-zero 中 延迟操 ...
- Pyhton中获取列表的索引
index方法 list_a= [12,213,22,2,32] for a in list_a: print(list_a.index(a)) 结果: 0 1 2 3 4 如果列表的没有重复项的话那 ...
- day27 Pyhton 面向对象02 类和对象的命名空间
一.内容回顾 类:具有相同属性和方法的一类事务 # 描述一类事务轮廓的一个机制 #商品/用户/店铺 对象/实例: 对象(实例)就是类的实例化 # 对象就是类的一个具体的表现 #某一件特定的商品/某个人 ...
- Linux系统编程 —线程同步概念
同步概念 同步,指对在一个系统中所发生的事件之间进行协调,在时间上出现一致性与统一化的现象. 但是,对于不同行业,对于同步的理解略有不同.比如:设备同步,是指在两个设备之间规定一个共同的时间参考:数据 ...
- 接口管理平台Yapi
1.介绍 YApi 是由去哪儿移动架构组推出的一款开源项目,是高效.易用.功能强大的 api 管理平台,旨在为开发.产品.测试人员提供更优雅的接口管理服务. 官网:https://yapi.ymfe. ...
- 【C语言C++编程学习笔记】一种很酷的 C 语言技巧,灵活运用编程技巧让你写代码事半功倍!
C语言常常让人觉得它所能表达的东西非常有限.它不具有类似第一级函数和模式匹配这样的高级功能.但是C非常简单,并且仍然有一些非常有用的语法技巧和功能,只是没有多少人知道罢了. ☆ 指定的初始化 很多人都 ...
- Zookeeper(1)---初识
一.ZK简述 Zookeeper,它是一个分布式程序的协调服务,它主要是用来解决分布式应用中的一些数据管理问题,比如集群管理,分布式应用配置,分布式锁,服务注册/发现等等. 它是一个类似于文件系统的树 ...
- python文件管道 下载图集
# -*- coding: utf-8 -*- import re from time import sleep import scrapy from scrapy.linkextractors im ...