vue3:Ref全家桶

29 篇文章 1 订阅
19 篇文章 1 订阅

ref

接受一个内部值并返回一个响应式且可变的 ref 对象。ref 对象仅有一个 .value property,指向该内部值。

非响应式:

<template>
  <div>
    <span>{{ msg }}</span>
    <el-button @click="handleChangeMSG">change msg</el-button>
  </div>
</template>
<script setup lang="ts">
let msg:string = 'lcy666'
const handleChangeMSG = ():void => {
  msg = 'lcy888'
}
</script>

使用ref定义变量实现响应式

<template>
  <div>
    <span>{{ msg }}</span>
    <el-button @click="handleChangeMSG">change msg</el-button>
  </div>
</template>
<script setup lang="ts">
import { ref, Ref } from "vue";
// Ref:是TS对应的类型
let msg: Ref<string> = ref("lcy666");
const handleChangeMSG = (): void => {
  // 注意:被ref包裹的变量,在赋值的时候需要给变量的.value赋值
  msg.value = "lcy888";
};
</script>

----------------ts的另一种写法--------------

<template>
  <div>
    <span>{{ msg }}</span>
    <el-button @click="handleChangeMSG">change msg</el-button>
  </div>
</template>
<script setup lang="ts">
import { ref } from "vue";
// 也可以书写为如下:
let msg = ref<string | number>("lcy666");
const handleChangeMSG = (): void => {
  // 注意:被ref包裹的变量,在赋值的时候需要给变量的.value赋值
  msg.value = "lcy888";
};
</script>

unref

如果参数是一个ref,则返回内部值,否则返回参数本身。这是 val = isRef(val) ? val.value : val 的语法糖函数。

<template>
  <div>首页~~~~~~~~~</div>
</template>
<script setup lang="ts">
import { ref, Ref, unref } from "vue";
const getNumber = (num: number | Ref<number>): number => {
  return unref(num);
};
const number = 10;
const refNumber = ref<number>(10);
console.log("number", getNumber(number)); // number 10
console.log("refNumber", getNumber(refNumber)); //refNumber 10
</script>

toRef

可以用来为源响应式对象上的某个 property 新创建一个 ref。然后,ref 可以被传递,它会保持对其源 property 的响应式连接。通俗来讲就是相当于对象的浅拷贝。

1、原始对象是响应式对象,数据更新,视图更新

<template>
  <div>首页~~~~~~~~~</div>
  <el-button @click="add">增加fooRef</el-button>
  <el-button @click="add1">增加state.foo</el-button>
  <div>fooRef---{{fooRef}}</div>
  <div>state.foo---{{state.foo}}</div>
</template>
<script setup lang="ts">
import {reactive, toRef} from 'vue'
const state = reactive({
  foo: 1,
  bar: 2
})
const fooRef = toRef(state, 'foo')
const add = ()=>{
  fooRef.value++
  console.log(state.foo)
  console.log(fooRef.value)
}
const add1 = ()=>{
  state.foo++
  console.log(state.foo)
  console.log(fooRef.value)
}
</script>

2、原始数据是非响应式对象,数据更新,视图不更新

<template>
  <div>
    <button @click="handleChange">change</button>
    {{ state }}
  </div>
</template>
 
<script setup lang="ts">
import { reactive, toRef } from 'vue'
const obj = {
  foo: 1,
  bar: 1
}
// bar 转化为响应式对象
const state = toRef(obj, 'bar')
const handleChange = () => {
  state.value++
  console.log(obj, state);
}
</script>

toRefs

批量创建ref对象---解构,主要是方便使用(普通的直接解构会使变量失去响应式)

<template>
  <div>
    {{ foo }} --- {{ bar }}
  </div>
</template>
 
<script setup lang="ts">
import { reactive, toRefs } from 'vue'
const obj = reactive({
   foo: 1,
   bar: 1
})
 
let { foo, bar } = toRefs(obj)
</script>

isRef

用于检测值是否是一个ref对象

<script setup lang="ts">
import { ref, isRef, Ref } from "vue";
const refNum: Ref<number> = ref(2);
const norNum: number = 2;
console.log(isRef(refNum)); // true
console.log(isRef(norNum)); // false
</script>

customRef

创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制。它需要一个工厂函数,该函数接收 track 和 trigger 函数作为参数,并且应该返回一个带有 get 和 set 的对象。

<template>
  <div>首页~~~{{name}}</div>
  <el-button @click="changeName">按钮</el-button>
</template>
<script setup lang="ts">
import { customRef } from "vue";
function myRef<T>(value:T){
  return customRef((track, trigger)=>{
    return {
      get(){
        track();
        return value
      },
      set(newVal:T){
        trigger();
        value = newVal
      }
    }
  })
}
let name = myRef<string>('lcy');
const changeName = ()=>{
  name.value='lcy666'
}
</script>

shallowRef

创建一个跟踪自身 .value 变化的 ref,但不会使其值也变成响应式的

1、修改属性不是响应式的

<template>
  <div>首页~~~{{ author }}</div>
  <el-button @click="changeAuthor">按钮</el-button>
</template>
<script setup lang="ts">
import { shallowRef, Ref } from 'vue'
interface Obj {
  name: string
}
let author: Ref<Obj> = shallowRef({
  name: 'lcy'
})
const changeAuthor = () => {
  author.value.name = 'lcy666'
  console.log(author.value);
}
</script>

 2、直接修改为另一个对象是响应式的

<template>
  <div>首页~~~{{ author }}</div>
  <el-button @click="changeAuthor">按钮</el-button>
</template>
<script setup lang="ts">
import { shallowRef, Ref } from 'vue'
interface Obj {
  name: string
}
let author: Ref<Obj> = shallowRef({
  name: 'lcy'
})
const changeAuthor = () => {
  author.value = {
    name:'lcy666'
  }
  console.log(author.value);
}
</script>

triggerRef

手动执行与 shallowRef 关联的任何作用 (effect),可以理解为强制更新

还是上边shallowRef的第一个例子,配合triggerRef:

<template>
  <div>首页~~~{{ author }}</div>
  <el-button @click="changeAuthor">按钮</el-button>
</template>
<script setup lang="ts">
import { shallowRef, Ref,triggerRef } from 'vue'
interface Obj {
  name: string
}
let author: Ref<Obj> = shallowRef({
  name: 'lcy'
})
const changeAuthor = () => {
  author.value.name = 'lcy666'
  console.log(author.value,'triggerRef')
  triggerRef(author)
}
</script>

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值