• 学习vue3第四节(ref以及ref相关api)


    主要记录以下api:ref()、isRef()、unref()、 shallowRef()、triggerRef()、customRef()

    1、ref() 定义

    接受一个内部值,返回一个响应式的、可更改的 ref 对象,此对象只有一个指向其内部值的属性 .value,.value属性用于追踪并且存储响应式数据的值(包括对象),当响应式对象变化时会自动追踪更新视图;
    如果将一个对象类型赋值给 ref(),那么这个对象将通过 reactive() 转为具有深层次响应式的对象。这也意味着如果对象中包含了嵌套的 ref,它们将被深层地解包
    如图:
    在这里插入图片描述

    2、ref使用

    ref() 接收的数据,在js中使用需要.value作为唯一的键引用,而在模板中使用只需要直接使用即可,不需要再.value,因vue模板会自动解析ref类型数据;
    如图:

    <template>
    	 年龄:{{ age }}
    	 <br>
    	 姓名:{{ name }}
    </template>
    <script setup>
    	import { ref,  reactive, computed, onMounted, onActivated, unref } from 'vue'
    	const age = ref(0)
    	const name = ref('Andy')
    	onMounted(() => {
    	  console.log('==age==', age.value)
    	  console.log('==name==', name.value)
    	})
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    3、ref() 接收对象类型时

    ref() 接收的对象类型若要里面的属性保持响应式,需要使用.value的方式进行单个属性赋值,如果将声明对象整体赋值,则会导致响应式失效,如:unNormalMan

    
      unNormalMan{{ JSON.stringify(unNormalMan) }}
      <br>
      <button @click="handleChangeNormal">unNormalMan</button>
      // 声明为响应式对象
    let unNormalMan = ref({
      job: '不知道',
      love: '猜猜'
    })
    // 整体赋值后变成普通对象,视图不会更新
    const handleChangeNormal = () => {
      unNormalMan = {
        a: '111',
        b: '222'
      }
      console.log('=handleChangeNormal==unNomalMan', unNormalMan)
      console.log('=change=unRef', unref(unNormalMan))
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    在这里插入图片描述

    // .value 形式单个赋值可以保持响应式
    const person = ref({
      job: '搬砖',
      love: '象棋'
    })
    
    const handleChangeJOb = () => {
      person.value.job = person.value.job + '$'
      const { job } = person.value
      console.log('===job=', job) // 搬砖$ 同样页面视图也会更新
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

    4、ref() 优缺点

    响应式数据:ref函数可以让我们轻松地创建响应式数据,无需使用Vue2中的data选项或this关键字。
    支持所有类型:与Vue2的data选项不同,ref函数可以用于创建任何类型的响应式数据,包括对象和数组。
    逻辑复用灵活:通过使用ref函数,我们可以更容易地在不同的组件和逻辑块之间共享和复用状态。
    注意:
    使用 ref 函数创建的响应式数据,在修改值时,必须通过 .value 属性来访问和修改。
    ref 函数返回的响应式引用对象是不可变的,即你不能将新的值赋给整个引用对象,而只能通过 .value 属性来修改内部的值。
    ref 函数可以用于创建任何类型的响应式数据,包括基本类型、对象、数组等。

    5、ref其他属性 isRef unRef shallowRef triggerRef customRef ,toRef toRefs 下节结合reactive 介绍

    5.1、isRef() 判断一个对象或者值是否为ref类型,返回一个布尔值

    const personMen = ref('优秀的')
    console.log(isRef(personMen)) // true
    const norefObj = {a:'333'}
    console.log(isRef(norefObj)) // false
    
    • 1
    • 2
    • 3
    • 4

    5.2、unref() 传入的对象如果是ref() 值或对象,则会返回 person.vue d的代理对象proxy;相反,如果是普通的对象或值,则会原样返回
    如图:

    let unNormalMan = ref({
      job: '不知道',
      love: '猜猜'
    })
    console.log('=000=unRef', unref(unNormalMan))
    // Proxy:{...}
    
    const per = '测试'
    console.log(unref(per)) // 测试
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    5.3、shallowRef()
    浅层的响应式声明,只针对.value进行响应式,而不会进行深层次的递归,即.value.xxx 不是响应式的,主要针对的是复杂类型的数据结构,
    如:

    const pet = shallowRef({
      job: '专业搬砖'
    })
    
    pet.value = { job: '躺平梦想'} // 会触发视图更新,响应式的
    pet.value.job = '响应不了' // 不是响应式的,
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    5.4、triggerRef
    强制触发依赖于浅层的Ref副作用,triggerRef() 会使浅层的响应式突变为深层的响应式,强制更新视图,比如使用shallowRef 处理的对象,响应式只能是浅层的,如果想要值更改时候也发生变化,则需要如下

    const perObj = shallowRef({
      job: '测试'
    })
    
    const handleChangePerObj = () => {
      perObj.value.job = '搬砖的'
      triggerRef(perObj) // 这样在模板中使用的 {{ perObj.job }} 会更新为 “搬砖的”,如果不使用 triggerRef() 则不会更新视图
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    5.5、customRef
    创建一个工厂函数,显示的声明对其依赖追踪触发的控制条件;
    即:创建的工厂函数中返回 set() get() 方法对象,通过set()自主控制触发时机,比如防抖
    防抖代码:

    import { customRef } from 'vue'
    
    export function useDebouncedRef(value, delay = 500) {
      let timeout
      return customRef((track, trigger) => {
        return {
          get() {
            track()
            return value
          },
          set(newValue) {
            clearTimeout(timeout)
            timeout = setTimeout(() => {
              value = newValue
              trigger()
            }, delay)
          }
        }
      })
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    // 使用如下:
    <script setup>
    import { useDebouncedRef } from './debouncedRef'
    const myRefVal = useDebouncedRef('测试防抖')
    </script>
    
    <template>
      <input v-model="myRefVal" />
    </template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • 相关阅读:
    基于身份的分段:三种技术路线解析与建议
    用于生物分子修饰的Alkyne NHS ester,906564-59-8
    【科技与狠货】云盘变硬盘
    基于 dynamic-datasource 实现 DB 多数据源及事物控制、读写分离、负载均衡解决方案
    智慧树\知到——程序设计基础(C语言)入门篇第六章到第十章测试答案
    爬动漫“上瘾”之后,放弃午休,迫不及待的用Python薅了腾Xun动漫的数据,啧啧啧
    DEJA_VU3D - Cesium功能集 之 055-国内外各厂商地图服务地址汇总说明
    学习微信小程序 Westore
    Docker基本操作
    恐龙做梦都想要的能力:人类首次小行星撞击实验
  • 原文地址:https://blog.csdn.net/weixin_39593730/article/details/136664370