Vue3的Ref使用

117 阅读1分钟

“我正在参加「掘金·启航计划」”

1. ref

深层次响应,接受一个内部值并返回一个响应式且可变的 ref 对象。ref 对象仅有一个 .value property,指向该内部值。注意被ref包装之后需要.value 来进行赋值

<template>
  <div>
    <button @click="changeMsg">修改</button>
    <div>{{ message }}</div>
  </div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
let message = ref<string>("我是message")
const changeMsg = () => {
   message.value = "改变了"
}
</script>
 
<style>
</style>

2. isRef

判断是不是一个ref对象

import { ref, isRef } from 'vue'
let message = ref<string | number>("我是message")
let notRef:number = 123
const changeMsg = () => {
  message.value = "change msg"
  console.log(isRef(message)); //true
  console.log(isRef(notRef)); //false
}

3. shallowRef

浅层次响应,创建一个跟踪自身 .value 变化的 ref,但不会使其值也变成响应式的,修改其属性是非响应式的,改变 .value 的值才是响应式的

<template>
  <div>
    <button @click="changeMsg">修改</button>
    <div>{{ message }}</div>
  </div>
</template>
 
<script setup lang="ts">
import { ref, shallowRef } from 'vue'
let message = ref({ name: 'mark' })
let message2 = shallowRef({
  name: "jack"
})
 
const changeMsg = () => {
  // 这样页面上并不会响应式改变
  message2.value.name = '改变了'
  // 这样才会改变
  message2.value = {name: '改变了'}
}
</script>
 
<style>
</style>

refshallowRef 不能在一起修改,否则shallowRef会被ref影响,因为 ref 底层调用了triggerRef(value)

<template>
  <div>
    <button @click="changeMsg">修改</button>
    <div>{{ message }}</div>
  </div>
</template>
 
<script setup lang="ts">
import { ref, shallowRef } from 'vue'
let message = ref({ name: 'mark' })
let message2 = shallowRef({
  name: "jack"
})
 
const changeMsg = () => {
  message.value.name = '我是ref'
  // 这样用shallowRef包裹的值页面上就会响应式改变
  message2.value.name = '我被ref影响了'
}
</script>
 
<style>
</style>

4. triggerRef 

会强制更新页面DOM

这样也是可以改变值的

<template>
  <div>
    <button @click="changeMsg">修改</button>
    <div>{{ message }}</div>
  </div>
</template>
 
<script setup lang="ts">
import { shallowRef, triggerRef } from 'vue'
let message = shallowRef({
  name: "jack"
})
 
const changeMsg = () => {
  message.value.name = '大满'
  triggerRef(message)
}
</script> 
 
<style>
</style>

5.customRef

自定义ref 

customRef 是个工厂函数要求我们返回一个对象 并且实现 get 和 set  适合去做防抖之类的

<template>
  <div ref="div">Ref</div>
  <hr>
  <div>
    {{ name }}
  </div>
  <hr>
  <button @click="change">修改 customRef</button>
</template>
 
<script setup lang='ts'>
import { ref, reactive, onMounted, shallowRef, customRef } from 'vue'
// 使用ref可以获取dom对象,就不用document.querySelector来获取节点了
const div = ref<HTMLDivElement>()
onMounted(() => {
  console.log(div.value)
})
function myRef<T = any>(value: T) {
  let timer:any;
  return customRef((track, trigger) => {
    return {
      get() {
       // 收集依赖
        track()
        return value
      },
      set(newVal) {
        clearTimeout(timer)
        timer =  setTimeout(() => {
          console.log('触发了set')
          value = newVal
          // 触发依赖
          trigger()
        },500)
      }
    }
  })
}
 
const name = myRef<string>('jack')
const change = () => {
  name.value = '改变了'
}
 
</script>
<style scoped>
</style>