• 简单直观的搞懂Vue3的ref、reactive、toRef、toRefs


    转载:https://blog.csdn.net/weixin_45517927/article/details/116016436

    相对于Vue2来说,Vue3最大的突破就是 Composition API 。与现有的 Option API 截然不同。他的好处可以总结为两点

    更集中的逻辑关注点
    更方便的函数逻辑复用机制
    不整废话,直接上货。

    作用
    首先需要明确这四个函数都是用于在 setup 中创造 响应式变量 的。明确了这一前提,再分类讨论。

    区分
    这四个函数分为两类,可触发页面改变与不可触发页面改变。在我没有完全搞懂每个函数具体的作用时,对这四个各面临的场景及各自的特性是不大能有一个明确的理解的。很容易被混淆。

    ref、reactive 可触发页面改变
    区别

    ref可用于任何类型的数据创建响应式,reactive只用于创建引用类型数据的响应式。
    注意
    ref对引用类型变量创建响应式其根本是当你给ref传入引用类型则调用reactive方法为其创建响应式。

    我为input进行双向绑定 ref 创建的数据,并且注册一个input事件来查看对原始数据的影响。

    ref

    // template 
    <div>
        <input type="text" v-model="refVal" @input="inputRefHander" />
        {{ refVal }}
    </div>
    
    // js
    let otherName = 'chris';
    const refVal = ref(otherName);
    const inputRefHander = () => {
        console.log(`ref:::refVal: ${refVal.value}, 原始数据: ${otherName}`);
    }

    通过打印出来的信息可以查看,ref 并不会影响原始数据。

    注意: ref返回一个对象,所以在非模板中,使用 ref 创建的变量应通过 .value 的形式访问变量值。在模板中则不用,它会自动展开为内部值。

    reactive
    我同样对input做相同操作监测 reactive 返回的数据变化。

    // template 
    <div>
        <input type="text" v-model="reactiveVal.target" @input="inputreactiveHander" />
        {{ reactiveVal.target }}
    </div>
    
    // js
    const obj = { type: 'obj', target: '5' }
    const reactiveVal = reactive(obj);
    const inputreactiveHander = () => {
        console.log('reactive:::', reactiveVal, "原始数据:::", obj);
    }

    通过打印可以很明显的看出,原始数据也被改变。

    注意:

    不可使用解构的方式定义响应式变量,会破坏响应性。所以老老实实的去访问属性就完事儿了,不要图那一两个单词的便利。
    toRef、toRefs 不可触发页面改变
    上面两个介绍了,ref 和 reactive 可以改变页面。接下来这两个则不能去改变页面,但是数据还是会遵循响应式。

    区别、特点:

    toRef 用于创建对象指定的属性响应式,换句话说就是只能控制一个对象中的一个属性。
    toRefs 用于创建对象响应式。
    他们对响应式的处理你可以理解为: toRef 类似 ref, toRefs 类似 reactive

    toRef
    还是同样的配方,还是同样的代码

    // template
    <div class="item">
        <input type="text" v-model="toRefVal" @input="inputToRefHander" />
        {{ toRefVal }}
    </div>
    
    // js
    const obj = { type: 'obj', target: '5' }
    const toRefVal = toRef(obj, 'target');
    const inputToRefHander = () => {
          console.log("toRef:::", toRefVal, "原始数据:::", obj);
    }

    toRef 接受两个参数:

    1. 需要给属性创建响应式的对象
    2. 需要创建响应式的属性

    通过打印的结果很容易看出,toRef是能改变原始数据的。从页面上也能看出,并不能触发页面改变。

    toRefs
    // template
    <div>
        <input type="text" v-model="target" @input="inputToRefsHander" />
        {{ target }}
    </div>
    
    // js
    const obj = { type: 'obj', target: '5' }
    const { target } = toRefs(obj);
    const inputToRefsHander = () => {
        console.log("toRefs:::", target, "原始数据:::", obj);
    }

    依旧从打印结果中可以看出,原始数据被改变,页面没有被触发。但从我的写法上应该可以注意到,toRefs 返回的对象,随便解、随便构。丝毫不会影响值的响应性。

    到这里也就写完了,不过还是要提一句setup基础知识。

    ref、reactive、toRef、toRefs 这些方法 均需从 vue 中导入到组件。
    ref、reactive、toRef、toRefs 创建的变量在 setup 中都需要 return { ... } 抛出才可在页面使用,除非你是为props创建响应式。
    最后总结成表格方便大家忘记特性的时候查阅,不过这么简单应该不会忘记( 没错,我就是单纯的想整个表格 )。

    类型 是否触发页面改变 是否可以解构
    ref      是 否
    reactive     是 否
    toRef      否 否
    toRefs    否 是

  • 相关阅读:
    JAVA中获取当前系统时间
    struts2文件下载及 <param name="inputName">inputStream</param>的理解
    struts2文件下载,动态设置资源地址
    IE8上传文件时文件本地路径变成"C:fakepath"的问题
    Java设置session超时(失效)的三种方式
    学一点Git--20分钟git快速上手
    关于服务器响应,浏览器请求的理解以及javaWeb项目的编码问题
    GBK、GB2312、iso-8859-1之间的区别
    mysql的多表查询
    mysql错误:“ Every derived table must have its own alias”(每个派生出来的表都必须有一个自己的别名)
  • 原文地址:https://www.cnblogs.com/lst619247/p/15393146.html
Copyright © 2020-2023  润新知