reactive ref toRef toRefs


// 判断对象是否是对象
const isObject = val => val !== null && typeof val === 'object';export function reactive(target) {if (!isObject(target)) return;const handler = {get(target, key, receiver) {let result = Reflect.get(target, key, receiver);track(target, key)return result},set(target, key, value, receiver) {let oldValue = Reflect.get(target, key, receiver)let result = true;if (oldValue !== value) {result = Reflect.set(target, key, value, receiver);trigger(target, key)}return result}}return new Proxy(target, handler)
}let activeEffect = null;
export function watchEffect(effect) {activeEffect = effect;effect()activeEffect = null
}let targetMap = new WeakMap()
function track(target, key) {if (!activeEffect) returnlet depsMap = targetMap.get(target);if (!depsMap) {targetMap.set(target, (depsMap = new Map()))}let deps = depsMap.get(key);if (!deps) {depsMap.set(key, (deps = new Set()))}deps.add(activeEffect)}function trigger(target, key) {const depsMap = targetMap.get(target)if (!depsMap) {return}let deps = depsMap.get(key);if (deps) {deps.forEach(effect => {effect()})}
}// 判断一个对象是不是对象 是的话就用reactive代理
const convert = val => (isObject(val) ? reactive(val) : val)
class RefImpl {constructor(rawValue) {this._rawValue = rawValue;this.__v__isRef = true;// 判断 _rawValue 是否是一个对象// 如果是对象调用reactive使用 proxy来代理// 不是返回 _rawValue 本身this._value = convert(rawValue)}get value() {track(this, 'value')return this._value}set value(newValue) {if (newValue !== this._value) {this._rawValue = newValue;this._value = convert(this._rawValue)trigger(this, 'value')}}
}export function ref(rawValue) {return new RefImpl(rawValue)
}class ObjectRefImpl {constructor(proxy, key) {this._proxy = proxy;this._key = key}get value() {return this._proxy[this._key]}set value(newValue) {this._proxy[this._key] = newValue}
}export function toRef(proxy, key) {return new ObjectRefImpl(proxy, key)
}export function toRefs (proxy) {const ret = proxy instanceof Array ? new Array(proxy.length) : {}for (let key in proxy) {ret[key] = toRef(proxy, key)}return ret
}
<script type="module">import { reactive, watchEffect, ref, toRef, toRefs } from './reactive.js'const obj = reactive({name: 'qqq',age: 23})// let data = ref(1)// let data1 = toRef(obj, 'age')const { name, age } = toRefs(obj)watchEffect(() => {console.log(name.value);console.log(age.value);// console.log(obj.age);// console.log(data.value);// console.log(data1.value);})// obj.age++// data.value++obj.age++
</script>

手写简单vue3响应式原理(reactive ref toRef toRefs)相关推荐

  1. vue3响应式原理之Ref

    theme: fancy 一. Ref 用法 这是 ref 最基本的用法,返回来的count是一个响应式的代理值 const count = ref(0) 二. 实现 1. ref 函数 我们调用的r ...

  2. vue2和vue3响应式原理

    vue2响应式原理:核心使用Object.defineProperty给属性定义get和set方法 注意:对象的多次递归,针对数组需要重写数组方法 函数劫持:把函数内部进行重写同时继续调用老的方法,在 ...

  3. vue2的响应式原理学“废”了吗?继续观摩vue3响应式原理Proxy

    一文了解Vue3的响应式原理 一.

  4. Vue3 响应式原理

    如何实现响应式 作为一个高阶的概述,我们需要做到以下几点: 当一个值被读取时进行追踪 当某个值改变时进行检测 重新运行代码来读取原始值 Vue如何知道哪些代码在执行 为了能够在数值变化时,随时运行我们 ...

  5. vue3响应式原理-reflect

    proxy负责对某个数据进行增删改查的监听,不过vue3底层不是直接对target进行如下的简单操作.而是利用es6的window.reflect 利用reflect取一个对象的属性 利用reflec ...

  6. vue3 响应式 API 之 ref

    ref 是最常用的一个响应式 API,它可以用来定义所有类型的数据,包括 Node 节点和组件. 没错,在 Vue 2 常用的 this.$refs.xxx 来取代 document.querySel ...

  7. vue3.0响应式原理.reactive watchEffect

    固定值 let activeEffect; class Dep {constructor(value) {this.subscribes = new Set()this._value = value} ...

  8. 深入了解Vue 2响应式原理,并手写一个简单的Vue

    1. Vue 2的响应式原理 Vue.js 一个核心思想是数据驱动.所谓数据驱动是指视图是由数据驱动生成的,对视图的修改,不会直接操作 DOM,而是通过修改数据.vue.js里面只需要改变数据,Vue ...

  9. Vue3的响应式原理解析

    Vue3的响应式原理解析 Vue2响应式原理回顾 // 1.对象响应化:遍历每个key,定义getter.setter // 2.数组响应化:覆盖数组原型方法,额外增加通知逻辑 const origi ...

最新文章

  1. 安装hadoop下的sqoop1.99.3及配置问题全解决
  2. UTF-8,UTF-16和UTF-32
  3. 每日一皮:当项目完工,开发进行演示时
  4. 桌面虚拟化“寻人行动”-转裁
  5. exchange系列(四)如何保护exchange邮件服务器的安全
  6. Python中文编码问题详解
  7. Makefile系列学习(博客)
  8. python豆瓣mysql_python操作mysql
  9. MyBatis 简介、 环境搭建、数据库连接池、查询方式
  10. 解决MySQL Workbench导出低版本MySQL时报错Unknown table ‘column_statistics’ in information_schema的问题
  11. python 在线培训费用-python培训费需要多少钱?
  12. JWT教程_2 SpringSecurity与JWT整合
  13. 盘点百度开放云编程马拉松八大亮点
  14. 来看看小夏的链表讲解吧---从单链表到输入输出,查找元素,删除结点。---谨以此文祝朋友们生日快乐与官宣发糖。
  15. 飞秋在使用高分辨率的显示器时字体太小,应该这样设置就和以前一样
  16. 袁国宝:董明珠的小倔强!
  17. Mentor.Graphics.FloTHERM.XT.2.3+Mentor.Graphics.Flowmaster.7.9.4
  18. 方块 游戏界面java_JAva 判断方块游戏清除方法
  19. MPC5748G开发笔记-----MPC5748G程序跑飞uSDHCDriverIRQHandler
  20. 二进制中,0为什么作为偶数,1为什么作为奇数?

热门文章

  1. 将Python文件打包成exe文件(超详细)
  2. 计算机专业学习模拟电子技术,什么是模拟电子技术?怎样才能学好模拟电子技术?...
  3. Python 字典按照key字母升序
  4. PTA 7-93 解一元一次方程
  5. PHP性能分析:Xhprof介绍
  6. iSpring Suite教程:iSpring Suite 9系统要求(上)
  7. 牛人用 Rust 重写了 Apache Spark,并把它开源了
  8. 终极指南:如何为iOS8应用制作预览视频
  9. 9.2.3 Python图像处理之图像数学形态学-二值形态学应用-区域填充
  10. vue自适应各种屏幕布局