Vue3中ref与reactive的详解与扩展

2022-04-15 0 1,275
目录
  • 一、ref和reactive
    • 1.reactive
    • 2.ref
  • 二、shallowRef和shallowReactive
    • 1. ref和shallowRef
    • 2. reactive和shallowReactive
  • 三、toRaw
    • 四、markRaw
      • 五、toRef和toRefs
        • 1. ref
        • 2.  toRef
        • 3.  toRefs
      • 总结

        一、ref和reactive

        死死记住:ref本质也是reactive,ref(obj)等价于reactive({value: obj})

        • vue3中实现响应式数据的方法是就是使用ref和reactive,所谓响应式就是界面和数据同步,能实现实时更新
        • vue2中响应式是通过defineProperty实现的,vue3中是通过ES6的Proxy来实现的

        Vue3中ref与reactive的详解与扩展

        1.reactive

        • reactive的参数必须是一个对象,包括json数据和数组都可以,否则不具有响应式
        • 如果给reactive传递了其他对象(如时间对象),默认情况下修改对象界面不会自动更新,如果想更新,可以通过给对象重新赋值来解决

        2.ref

        既然有了reactive,为何还要ref呢?当我们只想让某个变量实现响应式的时候,采用reactive就会比较麻烦,因此vue3提供了ref方法进行简单值的监听,但并不是说ref只能传入简单值,他的底层是reactive,所以reactive有的,他都有。还是那句老话:

        死死记住:ref本质也是reactive,ref(obj)等价于reactive({value: obj})

        • 在vue中使用ref的值,不用通过.value获取
        • 在js中使用ref的值,必须通过.value获取

        二、shallowRef和shallowReactive

        递归监听和非递归监听
        ref和reactive都属于递归监听,也就是数据的每一层都是响应式的,如果数据量比较大,非常消耗性能,非递归监听只会监听数据的第一层。

        1. ref和shallowRef

        • ref定义的数据每一层都是响应式数据
        • shallowRef定义的数据,只有第一层是响应式的,即只有在更改.value的时候才能实现响应式
        let age = ref({
              a: '1',
              f: {
                b: '2',
                s:{
                  c: '3'
                }
              }
            })
        //打印各层数据
        console.log(age);
        console.log(age.value);
        console.log(age.value.f);
        console.log(age.value.f.s);
        

        Vue3中ref与reactive的详解与扩展

        let age = shallowRef({
              a: '1',
              f: {
                b: '2',
                s:{
                  c: '3'
                }
              }
            })
        //打印各层数据
        console.log(age);
        console.log(age.value);
        console.log(age.value.f);
        console.log(age.value.f.s);
        

        Vue3中ref与reactive的详解与扩展

        使用shallowRef后,可以通过triggerRef()方法主动更新界面,实现界面刷新

        function doSome(){
          age.value.f.s.c = 'c';
          //主动更新界面
          triggerRef(age);
        }
        

        2. reactive和shallowReactive

        Vue3中ref与reactive的详解与扩展

        注意:shallowReactive没有类似triggerRef()的方法

        三、toRaw

        toRaw的出现是解决什么问题呢?

        有些时候我们不希望数据进行响应式实时更新,可以通过toRaw获取ref或reactive引用的原始数据,通过修改原始数据,不会造成界面的更新,只有通过修改ref和reactive包装后的数据时才会发生界面响应式变化。

        let obj1 = {...};
        //state和obj1是引用关系,state的本质是一个Proxy对象,其中引用了obj1
        let state = reactive(obj1);
        //通过toRaw方法获取到原始数据,其实是获取到obj1的内存地址,obj2和obj1是完全相等的
        let obj2 = toRaw(state)
        console.log(obj1 === obj2);//true
        

        有些同学会问,那直接使用obj1来修改数据不就行了吗?可关键是我们在使用reactive定义数据时一般不会先定义一个obj,再将他传给reactive,都是直接在reactive中写数据的。

        四、markRaw

        与toRaw不同,markRaw包装后的数据永远不会被追踪!

        暂时没发现有什么用处(手动狗头)

        let obj1 = {name: "lijing", age: 18}
        let obj2 = markRaw(obj1);
        //此时reactive包装的数据虽然是响应式对象,但是不会被跟踪,也不会产生效应式效果
        let state1 = reactive(obj2)
        
        console.log(obj1 === obj2);//true
        

        五、toRef和toRefs

        ref和toRef都是用来构造响应式数据,两者有什么区别呢,看两个例子

        1. ref

        复制,修改响应式数据不会影响以前的数据,数据发生改变界面就会自动更新

        转换后的是一个RefImpl类型

        Vue3中ref与reactive的详解与扩展

        可以看到,使用ref对一个对象的某个简单数据类型属性进行响应式改造后,通过修改响应式数据不会影响到原始数据,如上图中,通过state1修改值后,obj1中的a属性值没有发生变化。这里有个注意点:修改的这个属性必须是简单数据类型,一个具体的值,不能是引用,如果该属性也是一个对象,则会影响,因为对象—>引用!

        例如上面例子中,如果传入state1的是obj1.f,则情况完全不同

        //等价于let state1 = ref({b: '2',s: {c: '3'}})
        // 又等价于--->let state1 = reactive({value: {....}}})
        let state1 = ref(obj1.f);
        

        2.  toRef

        如果使用toRef来转换,则修改响应式数据会影响到原始数据,数据发生改变,但是界面不会自动更新

        转换后的是一个ObjectRefImpl类型

        Vue3中ref与reactive的详解与扩展

        ref类似深拷贝,toref类似浅拷贝

        3.  toRefs

        遍历对象中的所有属性,将其变为响应式数据,这是因为toRef只能传一个key,toRefs所达到的效果与toRef一样

        Vue3中ref与reactive的详解与扩展

        tips:目前用的最多的还是ref和reactive,其他东西一般是后期用来改善性能使用的。

        总结

        到此这篇关于Vue3中ref与reactive的文章就介绍到这了,更多相关Vue3 ref与reactive内容请搜索NICE源码以前的文章或继续浏览下面的相关文章希望大家以后多多支持NICE源码!

        免责声明:
        1、本网站所有发布的源码、软件和资料均为收集各大资源网站整理而来;仅限用于学习和研究目的,您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。 不得使用于非法商业用途,不得违反国家法律。否则后果自负!

        2、本站信息来自网络,版权争议与本站无关。一切关于该资源商业行为与www.niceym.com无关。
        如果您喜欢该程序,请支持正版源码、软件,购买注册,得到更好的正版服务。
        如有侵犯你版权的,请邮件与我们联系处理(邮箱:skknet@qq.com),本站将立即改正。

        NICE源码网 JavaScript Vue3中ref与reactive的详解与扩展 https://www.niceym.com/29319.html