• 【vue3】实现数据响应式(ref、shallowRef、trigger、reactive、shallowReactive、toRef、toRefs)


    一、ref、shallowRef、trigger

    ref支持所有类型
    可以粗略理解为 ref = shallowRef + triggerRef

    1、通过ref获取dom元素

    
    	<p ref="_ref">这是ref获取dom元素</p>
    	
    	 import {ref,shallowRef, triggerRef} from 'vue'
    	 const _ref = ref()
    	 console.log(_ref.value?.innerText)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2、实现数据响应

    
      import {ref,shallowRef, triggerRef} from 'vue'
      //ref
      type M = {
        name:string,
        age:number
      }
      const personObj= ref<M>(
        {
          name:'孙悟空',
          age:90
        }
      )
      const fn1= ()=>{
        personObj.value.name = '白骨精' //视图也会更新
        console.log(personObj)
      }
    
      //shallowRef
      const man = shallowRef ({name:'张三'})
      const fn1= ()=>{
        /**
         * man是shallowRef对象,直接更改value值不会更新视图,调用triggerRef强制更新
         * 并且会受ref变量personObj更改值的影响(personObj.value.name = '白骨精')
         * 所以ref和shallowRef不要写在一起
         * 可以粗略理解为 ref = shallowRef + triggerRef
         */
        man.value.name = '李四'  
        triggerRef(man)
        console.log(man) //视图会更新
    
      }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    二、reactive、shallowReactive

    reactive只接收引用类型 array、object、map
    shallowReactive与shallowRef的问题一样,shallowReactive只能响应第一层

    
    //对象场景
      type M2 = {
        name:string,
        age:number
      }
      let from = reactive<M2>({
        name:'yyx',
        age:18
      })
      from.age = 90 //不需要.value  和ref不一样,ref取值/赋值都需要.value
      
    //数组场景
      let list = reactive<string[]>([])
      list = ['aaa','bbb','ccc']
    
    //数据异步场景(从接口请求回来)
      /**
       * 异步数据不能直接 = 赋值
       * 通过push
       * 或者定义为对象,包裹起来
       */
       
      let list = reactive<string[]>([])
      setTimeout(() => {
        const res = ['aaa','bbb','ccc']
        list.push(...res)  //通过push注入值,不能直接 = 赋值
      }, 3000);
    
    	/**或者*/
    	
      let data = reactive<any>({
        list:[]
      })
    
      setTimeout(() => {
        const res = ['aaa','bbb','ccc']
        data.list = res
      }, 3000);
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    三、toRef、toRefs、toRaw

    只能对响应式的对象有用,非响应式的 视图毫无变化;
    reactive的值被解构出来丢失了响应式,这个时候就要用toRef、toRefs;
    为了单独提取对象中的一个,然后变成响应式,可以把toRef、toRefs理解为解构操作;

    
      import {reactive,toRef, toRefs,toRaw} from 'vue'
    
       /**
       * toRef
       * 一次性解构一个
      */
      const toRef_Obj = reactive({
        name:'游芸霞',
        nickname:'fenyin'
      })
      
      /**只更新视图,但是toRef_Obj内的数据并未变化 */
      let {name,nickname} = toRef_Obj
      name = 'youyunxia' //这样写toRef_Obj的name还是'游芸霞“
    
      /**双向响应式,视图、数据都发生变化 */
      let _toRef_name = toRef(toRef_Obj,'name')
      _toRef_name.value = 'youyunxia' //这样写toRef_Obj的name就会变成'youyunxia“
    
    
      /**
       * toRefs
       * 和toRef一样,只是toRefs一次性解构多个
      */
      let {name,nickname} = toRefs(toRef_Obj)
      name.value = '张三'
      console.log('toRefs========',name,nickname)
      
      /**
       * toRaw
       * 不想要响应式的proxy时,可以用toRaw转化
       */
      console.log('响应式=============',toRef_Obj)
      console.log('非响应式===========',toRaw(toRef_Obj))
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    toRaw()效果图
    在这里插入图片描述

  • 相关阅读:
    vue3 - Ts版本
    崇州羊马学校携手安道教育构建智慧校园,探索教学新突破
    GO微服务实战第八节 如何基于 Go-kit 开发 Web 应用:从接口层到业务层再到数据层
    微服务从代码到k8s部署应有尽有系列(四、用户中心)
    RAW socket
    【Python/Pytorch 】-- SVM算法
    GitHub上架即下架,《分布式系统人人都是架构师》全彩笔记开源
    Vue05/Vue组件子传父、props校验、Vue父子组件传值总结
    springboot+vue上传图片
    Netron【.pt转.torchscript模型展示】
  • 原文地址:https://blog.csdn.net/weixin_44171757/article/details/133786345