customRef与reactive和readonly

1、首先说下customRef.
①customRef 用于自定义返回一个ref对象,可以显式地控制依赖追踪和触发响应,接受工厂函数
②两个参数分别是用于追踪的 track 与用于触发响应的 trigger,并返回一个一个带有 get 和 set 属性的对象

import {customRef} from 'vue';
function useDebRef(value) {
	      return customRef((track, trigger) => {
	        return {
	          get() {
	            track()	//追踪当前数据
	            return value
	          },
	          set(newValue) {
	            value=newValue
	            trigger() //触发响应,即更新界面
	          },
	        }
	      })
	 }

//通过customRef返回的ref对象,和正常ref对象一样,通过x.value修改或读取值

ts类型声明

function customRef<T>(factory: CustomRefFactory<T>): Ref<T>
	type CustomRefFactory<T> = (
	  track: () => void,
	  trigger: () => void
	) => {
	  get: () => T
	  set: (value: T) => void
	}

customRef可以写自定义防抖函数

function selfDefineDebouncedRef(value, selfTime = 200) {
  let selfTimeout;
  return customRef((track, trigger) => {
    return {
      get() {
        track()
        return value
      },
      set(newValue) {
        clearTimeout(selfTimeout)
        selfTimeout = setTimeout(() => {
          value = newValue
          trigger()
        }, selfTime)
      }
    }
  })
}
//我们使用的时候直接在方法中调用   selfDefineDebouncedRef('hello word')

2、下面我们说下reactive,它可以接受数组以及对象这种复杂的数据类型,如果给他传基本数据类型他是有警告的。(源码当中会有判断数据类型,不是复杂数据类型会有警告。)

错误写法

import {reactive} from "vue"
let message = reactive<number[]>([]) //[]
settimeout(()=>{
   let arr = [1,2,3,4,4,5]
   message=arr  //这样是错误的,我们这样就改变了message的响应式活性。
},1000)

正确写法一

import {reactive} from "vue"
type D = {
  list:number[]
}
let message = reactive<D>({
   list:[]
}) //[]
settimeout(()=>{
   let arr = [1,2,3,4,4,5]
   message.list=arr  //这样是正确的
},1000)

正确写法二

import {reactive} from "vue"
let message = reactive<number[]>([]) //[]
settimeout(()=>{
   let arr = [1,2,3,4,4,5]
   message.push(...arr) //这样是正确的
},1000)

3、readonly

import {reactive,readonly} from "vue"
let person = reactive({
   name:"axin",
   age:30
})
let copyPerson = readonly(person)
copyPerson.age--  //这样会报错,因为readonly为只读,不可以改变

4、shallowReactive

import {shallowReactive} from "vue"
let msg = shallowReactive({
	name:"axin",
	nav:{
		bar:{
		  name:"hashvalue"
		}
    }
})
const changeA = ()=>{
  msg.name = 'yaojing'
}
const changeB =()=>{
	msg.nav.bar.name = 'xinzai'
}

//如果我们直接调用方法是可以改变值的,如下
changeA() //console.log(msg.name)  //yaojing
changeB()  //console.log(msg.nav.bar.name) //xinzai

//如果我们将方法添加到页面的按钮上再触发就不会这样嘞,就只可以触发changeA方法的视图更新,而changeB只是值变了视图没有更新。

总结:shallowReactive的用法是在生命周期挂载后触发使用的,只可以改变最外层对象的属性的值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

唐长老521

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值