我说ref才是响应式的老大没人反对吧?

由于上一篇文章已经写过reactive,所以ref就只需要考虑原始类型即可,引用类型只需要引进上一篇文章的reactive来实现引用类型的响应式。
reactive的手写

手写ref

其实我们在使用reactive和ref时一般考虑个人习惯,不过引用类型数据多时建议使用reactive。但是ref写起来简单还通用,ref是完胜reactive的。

ref函数

与reactive同样的人,ref开局出生就是独生子

js 复制代码
export function ref(val){//将原始类型数据变成响应式  引用类型也可以
    return createRef(val)
}

createRef

这里我们先判断val.__v_isRef是否为响应式,开始数据不会是响应式的,所以得先执行下面RefImpl类里面的操作

js 复制代码
function createRef(val){
    // 判断val是否已经是响应式
    if(val.__v_isRef){
        return val
    }

    // 将val变成响应式
    return new RefImpl(val)
}

RefImpl类

我们写ref当然不能只写它对原始类型有用,必须也能使用引用类型。这时就得从reactive那里借点东西过来了 reactive的手写。ref也需要进行依赖收集。

js 复制代码
class RefImpl{
    constructor(val){  //class类的语法
        //ref代理的对象身上的属性
        this.__v_isRef = true //给每一个被ref操作过的属性值添加标记
        this._value = convert(val)

    }

    get value(){ //age.value可以获取
        //为this对象做依赖收集
        track(this,'value')
        return this._value
    }
    //更新age
    set value(newVal){
        if(newVal !== this._value){
            this._value = convert(newVal)
            trigger(this,'value')//触发掉'value'上的所有副作用函数
        }
    }
}


function convert(val){
    if(typeof val!=='object' || val === null ){
        return val
    }else{
        return reactive(val)
    }

}
  1. this._value = convert(val):这行代码将传入的 val 值进行转换,并将转换后的值存储在 _value 属性中。convert 函数的作用是判断 val 的类型,如果是对象类型,则将其转换成响应式对象,否则保持原来的类型。通过将值存储在 _value 属性中,可以在后续的代码中通过 get value() 方法来获取该值。
  2. get value():这是使用了JavaScript 中的特殊属性访问器,可以通过age.value来获取ref里面的数据,而不是age.value(),简化了代码
  3. set value:当数据发送更新后,先通过convert判断数据类型,再通过reactive里面的trigger函数触发value里面所有副作用函数。
相关推荐
敏姐的后花园2 小时前
模考倒计时网页版
java·服务器·前端
AiXed3 小时前
PC微信WDA算法
前端·javascript·macos
博客zhu虎康4 小时前
React+Ant design
javascript·react.js·ecmascript
一只小阿乐8 小时前
react 封装弹框组件 传递数据
前端·javascript·react.js
533_9 小时前
[element-plus] el-tree 动态增加节点,删除节点
前端·javascript·vue.js
禁止摆烂_才浅9 小时前
前端开发小技巧-【JavaScript】- 获取元素距离 document 顶部的距离
前端·javascript·react.js
wshzd9 小时前
LLM之Agent(二十九)|LangChain 1.0核心组件介绍
前端·javascript·langchain
程序猿_极客9 小时前
Vue 2脚手架从入门到实战核心知识点全解析(day6):从工程结构到高级通信(附代码讲解)
前端·javascript·vue.js·vue2学习笔记
q***71859 小时前
海康威视摄像头ISUP(原EHOME协议) 摄像头实时预览springboot 版本java实现,并可以在浏览器vue前端播放(附带源码)
java·前端·spring boot
一只小阿乐9 小时前
vue3 使用v-model开发弹窗组件
javascript·vue.js·elementui