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响应式原理的更多相关文章

  1. 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# ...

  2. vue2.0与3.0响应式原理机制

    vue2.0响应式原理 - defineProperty 这个原理老生常谈了,就是拦截对象,给对象的属性增加set 和 get方法,因为核心是defineProperty所以还需要对数组的方法进行拦截 ...

  3. Vue 2.0 与 Vue 3.0 响应式原理比较

    Vue 2.0 的响应式是基于Object.defineProperty实现的 当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的 prop ...

  4. Vue3.0 响应式数据原理:ES6 Proxy

    Vue3.0 开始用 Proxy 代替 Object.defineProperty了,这篇文章结合实例教你如何使用Proxy 本篇文章同时收录[前端知识点]中,链接直达 阅读本文您将收获 JavaSc ...

  5. Vue3.0响应式实现

    基于Proxy // 弱引用映射表 es6 防止对象不能被回收 let toProxy = new WeakMap(); // 原对象: 代理过得对象 let toRaw = new WeakMap( ...

  6. Vue2.0响应式原理以及重写数组方法

    // 重写数组方法 let oldArrayPrototype = Array.prototype; let proto = Object.create(oldArrayPrototype); ['p ...

  7. vue2与vue3实现响应式的原理区别和提升

    区别: vue2.x: 实现原理: 对象类型:Object.defineProperty()对属性的读取,修改进行拦截(数据劫持): 数组类型:通过重写更新数组的一系列方法来进行拦截(对数组的变更方法 ...

  8. vue3剖析:响应式原理——effect

    响应式原理 源码目录:https://github.com/vuejs/vue-next/tree/master/packages/reactivity 模块 ref: reactive: compu ...

  9. 由浅入深,带你用JavaScript实现响应式原理(Vue2、Vue3响应式原理)

    由浅入深,带你用JavaScript实现响应式原理 前言 为什么前端框架Vue能够做到响应式?当依赖数据发生变化时,会对页面进行自动更新,其原理还是在于对响应式数据的获取和设置进行了监听,一旦监听到数 ...

随机推荐

  1. ansible-playbook流程控制-when条件判断

    1. ansible-playbook添加判断     when相当于shell脚本里的if 判断,when语句就是用来实现这个功能的,它是一个jinja2的语法,但是不需要双大括号,用法很简单  1 ...

  2. Linux就该这么学28期——Day05 vim编辑器与Shell命令脚本 (yum配置 网卡配置)

    vim 三种模式: 命令模式 按行操作 dd 剪切.删除 5dd dG   全删 yy 复制光标所在行 p 粘贴 u 撤销操作 / 搜索 /ab n  下一个 N   上一个 输入模式 a 当前光标处 ...

  3. centos7搭建docker环境

    Docker简介 Docker是一种虚拟化技术,用来将你的应用程序及其依赖的环境一起打包成一个镜像发布,使得在任何地方都能获得相同的运行环境. Docker 是一个开源项目,诞生于 2013 年初,最 ...

  4. pytest文档54-Hooks函数terminal打印测试结果(pytest_report_teststatus)

    前言 使用命令行执行pytest用例的时候,会在 terminal 终端打印整个用例的测试结果: .代表通过的用例 F代表失败的用例 E代表异常的用例 如果我们不喜欢这种报告结果,可以通过 pytes ...

  5. Shell Scripting 笔记

    Shell Scripting Tutorial Variables in the Bourne shell do not have to be declared, as they do in lan ...

  6. go视频提取音频

    package main import ( "bytes" "fmt" "log" "os" "os/exec ...

  7. 学了那么多 NoSQL 数据库 NoSQL 究竟是啥

    NoSQL 简史 NoSQL 一词最早出现于 1998 年,是 Carlo Strozzi 开发的一个轻量.开源.不提供 SQL 功能的关系数据库. 2009 年,Last.fm 的 Johan Os ...

  8. ServletContext使用介绍

    ServletContext是一个容器(域对象)可以存储键值对数据(String key,Object value),保存在ServletContext中的数据不仅可以提供给所有的servlet使用, ...

  9. 020_Typora使用

    目录 Typora使用 下载 安装 设置 使用 Typora使用 Typora插入本地图片为本地路径,网络上无法查看,所以建议只插入网络图片. 下载 百度搜索官网 下载 安装 设置 视图->显示 ...

  10. Java中的微信支付(1):API V3版本签名详解

    1. 前言 最近在折腾微信支付,证书还是比较烦人的,所以有必要分享一些经验,减少你在开发微信支付时的踩坑.目前微信支付的API已经发展到V3版本,采用了流行的Restful风格. 今天来分享微信支付的 ...