ref 函数实现代码

const a = ref(1);
function ref(value){
const wrapper = {value}
Object.defineProperty(wrapper,'__v_isRef',{
value: true
})
return reactive(wrapper)
}

  把新建一个对象,value 属性是原始值,再把对象交给 reactive 进行响应式处理。所以要获取 ref 的值要拿取其 value 属性。 这里还添加了 不可遍历、配置、改写的属性 __v_isRef。标识 ref 类型。

ref 还能够用于响应式丢失问题

解构和展开运算符 会让响应式数据失去响应 下面是例子

const obj = reactive({ foo: 1, bar: 2 });
let { foo, bar } = obj;
const target = {
...obj,
};
foo = 123;
target.foo = 2;
console.log(obj); const a = ref(1);
let { value } = a;
value = 456;
console.log(a);

  打印结果可以看出,解构和展开的属性已经没了和原来的响应式数据的联系,如何继续保持这种联系呢? 可用 toRef 和 toRefs API

toRef 代码实现

function toRef(target,key){
const wrapper = {
get value(){
return Reflect.get(target,key)
},
set value(newvalue){
return Reflect.set(target,key,newvalue)
}
}
Object.defineProperty(wrapper,'__v_isRef',{
value: true
})
return wrapper
}

  toRef 就是把对象的某个属性转为 ref 。实现和 ref 函数差不多,只不过 ref 是把新建的对象 交给 reactive 。

  而 toRef 是改写新建的对象的 value 属性的 get 方法和 set 方法,关联上目标对象属性。

toRefs 代码实现

function toRefs(target){
const wrapper = {}
for (let key in target) {
wrapper[key] = toRef(target,key);
}return wrapper
}

  toRefs 只是循环目标对象属性,调用 toRef

现在又有了新的问题,虽然把响应式丢失解决了,但是必须通过 value属性 才能访问,例子

const obj = reactive({ foo: 1, bar: 2 });
const target = {...toRefs(obj)};
target.foo.value

解决方案,创建一个代理对象,每次取值时是 ref 类型,返回 value 属性

function proxyRefs(target){
return new Proxy(target,{
get (target,key,receiver) {
const res = Reflect.get(target,key,receiver);
return res.__v_isRef ? res.value:res
},
set (target,key,newVal,receiver){
if(target[key].__v_isRef) {
Reflect.set(target[key],value,newVal,receiver)
return true
}
return Reflect.set(target,key,newVal,receiver)
}
})
}

   在vue 组件中,模板能不用 value 取到值,那是因为 setup 函数返回的数据会传递给 proxyRefs 函数进行处理。

reactive 也有自动调用 proxyRefs ,例子

const count = ref(1);
const obj = reactive(count);
obj.count // 1

vue设计与实现 第6章 ref 响应原理 笔记的更多相关文章

  1. linux及安全《Linux内核设计与实现》第一章——20135227黄晓妍

    <linux内核设计与实现>第一章 第一章Linux内核简介: 1.3操作系统和内核简介 操作系统:系统包含了操作系统和所有运行在它之上的应用程序.操作系统是指整个在系统中负责完成最基本功 ...

  2. 第四章初始CSS3预习笔记

    第四章 初始CSS3预习笔记 一: 1: 什么是CSS? 全称是层叠样式表;/通常又称为风格样式表,.他是用来进行网页风格设计的; 2:CSS的优势: 1>内容以表现分离,即使用u前面学习的HT ...

  3. 图解 TCP/IP 第六章 TCP与UDP 笔记6.1 传输层的作用

     图解 TCP/IP  第六章 TCP与UDP   笔记6.1 传输层的作用   传输层必须指出这个具体的程序,为了实现这一功能,使用端口号这样一种识别码.根据端口号,就可以识别在传输层上一层的应用程 ...

  4. Java程序设计(2021春)——第三章类的重用笔记与思考

    Java程序设计(2021春)--第三章类的重用笔记与思考 本章概览: 3.1 类的继承(概念与语法) 3.2 Object类(在Java继承最顶层的类) 3.3 终结类和终结方法(只能拿来用,不可以 ...

  5. Java程序设计(2021春)——第四章接口与多态笔记与思考

    Java程序设计(2021春)--第四章接口与多态笔记与思考 本章概览: 4.1 接口(接口的概念和声明接口.实现接口的语法) 4.2 类型转换 4.3 多态的概念 4.4 多态的应用 4.5 构造方 ...

  6. 《Linux内核设计与实现》课本第十八章自学笔记——20135203齐岳

    <Linux内核设计与实现>课本第十八章自学笔记 By20135203齐岳 通过打印来调试 printk()是内核提供的格式化打印函数,除了和C库提供的printf()函数功能相同外还有一 ...

  7. 《TCP/IP详解卷1:协议》第2章 链路层-读书笔记

    章节回顾: <TCP/IP详解卷1:协议>第1章 概述-读书笔记 <TCP/IP详解卷1:协议>第2章 链路层-读书笔记 <TCP/IP详解卷1:协议>第3章 IP ...

  8. 0003.5-20180422-自动化第四章-python基础学习笔记--脚本

    0003.5-20180422-自动化第四章-python基础学习笔记--脚本 1-shopping """ v = [ {"name": " ...

  9. 第二章 Javac编译原理

    注:本文主要记录自<深入分析java web技术内幕>"第四章 javac编译原理" 1.javac作用 将*.java源代码文件转化为*.class文件 2.编译流程 ...

  10. 学习Zookeeper之第3章Zookeeper内部原理

    第 3 章 Zookeeper 内部原理 3.1 选举机制 3.2 节点类型 3.3 stat 结构体 3.4 监听器原理   1)监听原理详解   2)常见的监听 3.5 写数据流程 第 3 章 Z ...

随机推荐

  1. 四、frp内网穿透服务端frps.ini各配置参数详解

    [必须]标识头[common]是不可或缺的部分 [必须]服务器IPbind_addr = 0.0.0.00.0.0.0为服务器全局所有IP可用,假如你的服务器有多个IP则可以这样做,或者填写为指定其中 ...

  2. Logstash:使用 Logstash 导入 CSV 文件示例

    转载自:https://elasticstack.blog.csdn.net/article/details/114374804 在今天的文章中,我将展示如何使用 file input 结合 mult ...

  3. Grafana配置Alert监控告警

    1.添加告警途径 这里以slack为例 测试是否可用 在slack上收到告警通知了 安装插件 # grafana-cli plugins install grafana-image-renderer ...

  4. 1_Linux

    一. Linux介绍 1.1 引言 在学习Linux之前, 大家先了解开发环境,生产,测试环境 开发环境: 平时大家大多是在Windows或者Mac操作系统下去编写代码进行开发,在开发环境中安装大量的 ...

  5. gin项目部署到服务器并后台启动

    前言 我们写好的gin项目想要部署在服务器上,我们应该怎么做呢,接下来我会详细的讲解一下部署教程. 1.首先我们要有一台虚拟机,虚拟机上安装好go框架. 2.将写好的项目上传到虚拟机上. 3.下载好项 ...

  6. Python 实验报告(第三周)

    一.实验目的和要求 1.熟练运用常见选择结构: 2.熟练运用for循环和while循环: 3.理解带else语句的循环结构执行过程和break.continue语句在循环中的作用. 二.实验环境 软件 ...

  7. The project was not built due to "Could not delete '/XXX/WebRoot/WEB-INF/classes/library'.". Fix the problem, then try refreshing this project and building

    在构建插件时提示如下错误: Description Resource Path Location Type The project was not built due to "Could n ...

  8. 死锁与Lock锁

    死锁1.死锁的理解:不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,就形成了线程的死锁 2.说明: 1)出现死锁后,不会出现异常,不会出现提示,只是所有的线程都处于阻塞 ...

  9. react.js+easyui 做一个简单的商品表

    效果图:     import React from 'react'; import { Form, FormField, Layout,DataList,LayoutPanel,Panel, Lab ...

  10. 【JavaWeb】学习笔记——Ajax、Axios

    Ajax Ajax 介绍 AJAX(Asynchronous JavaScript And XML):异步的JavaScript 和 XML AJAX 的作用: 与服务器进行数据交换:通过AJAX可以 ...