vue3之定义数据

只是用于展示的数据(非响应式数据)

  • 常规的定义变量,这是不具有响应式的,也就是无法更改当前的试图的值
<template>
  <div>
    <div>
      <button @click="changeMsg">修改msg</button>
      {{ msg }}
    </div>
  </div>
</template>

<script setup lang="ts">
// 这定义的变量 只是用于显示 不具有响应式
let msg: String = '菜鸡'
const changeMsg = () => {
  msg = '我是修改的msg'
}
</script>
  • 效果
    在这里插入图片描述

响应式数据 (Ref全家桶)

定义简单数据类型

  • 使用ref定义简单数据类型 具备响应式效果
  • 使用 Ref来限制 当前msg的数据类型
<template>
  <div>
    <div>
      <button @click="changeMsg">修改msg</button>
      <div>{{ msg2 }}</div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, Ref, reactive } from 'vue'
let msg2: Ref<String> = ref('菜鸡2')
const changeMsg = () => {
  msg2.value = '我是修改的msg2'
}
</script>
  • 效果
    在这里插入图片描述

判断是否为 ref对象(定义为响应式数据对象)

<template>
  <div>
    <div>
      <button @click="changeMsg">修改msg</button>
      <div>{{ msg2 }}</div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, Ref, isRef, reactive } from 'vue'
let msg2: Ref<String> = ref('菜鸡2')
const msg: Number = 1
const changeMsg = () => {
  msg2.value = '我是修改的msg2'
  console.log('判断是否为 ref定义的响应式数据', isRef(msg2)) // 判断是否为 ref定义的响应式数据 true
  console.log('判断是否为 ref定义的响应式数据', isRef(msg)) // 判断是否为 ref定义的响应式数据 false
}
</script>

shallowRef 定义简单数据类型的响应式

  • shallowRef:只处理简单数据类型的响应式, 不进行对象的响应式处理。
  • 使用场景:
  • 方式1
    • 直接修改表层的对象的数据,这是可以被监测到的响应式数据
<template>
  <div>
    <div>
      <button @click="changeMsg2">修改msg2</button>
      <div>msg2 -- {{ msg2 }}</div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { shallowRef, triggerRef } from 'vue'
// 使用shallowRef 定义的数据,只是表层具有响应式的,里层的数据则是没有响应式的
let msg2 = shallowRef({
  name: '菜鸡2',
})
const changeMsg2 = () => {
  // 修改表层的数据 可修改
  msg2.value = {
    name: '我是name',
  }
}
</script>
  • 效果
    在这里插入图片描述

  • 方式2

<template>
  <div>
    <div>
      <button @click="changeMsg1">修改msg1</button>
      <div>msg1 -- {{ msg1 }}</div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { shallowRef, triggerRef } from 'vue'
// 使用shallowRef 定义的数据,只是表层具有响应式的,里层的数据则是没有响应式的
let msg1 = shallowRef({
  name: '菜鸡1',
})
const changeMsg1 = () => {
  // msg1.value = 'xxxx' // 这种是 修改简单数据类型的方式 报错
  msg1.value.name = 'xxxx' // 若是使用 本地数据已经更改
  console.log('msg1', msg1.value)
  // {name: 'xxxx'} 但是由于 shallowRef 定义的数据,仅仅是表层数据为响应式,因此对象形式没有被监听到
  // 若是想要实现 监听,则可以使用 triggerRef() 包裹着当前需要更新的值
  triggerRef(msg1)
}
</script>
  • 效果
    在这里插入图片描述

shallowRef 不能和ref 同时使用

  • 注意点:shallowRef 和 ref不能一起写,会影响shallowRef 对视图的更新
    <div>
      <div>{{ aaa }}</div>
      <div>{{ bbb }}</div>
      <div>{{ b }}</div>
      <button @click="changeA">修改A</button>
      <button @click="changeb">修改b</button>
    </div>
    
type AAA = {
  name: string
}
let aaa = ref<AAA>({
  name: 'xzl'
})
let bbb = shallowRef<AAA>({
  name: 'xzl-b'
})
let b = shallowRef(0)
// 注意点:就是使用 shallowRef定义的数据,
const changeA = () => {
  // aaa.value.name = 'XZL'
  bbb.value.name = 'XZL-bbb' // 值修改了 但是视图不修改
  // b.value = 100
  console.log('a', aaa, 'b', bbb)
}
const changeb = () => {
  b.value = 100
}

在这里插入图片描述
在这里插入图片描述

customRef

  • customRef 可以用来创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制
  • 它需要一个工厂函数,该函数接收 track 和 trigger 函数作为参数,并且应该返回一个带有 get 和 set 的对象。
  • 其实大致意思就是,我们可以按照自己的业务需求去自定义封装一个 ref 对象,在其内部可以使用 get 和 set去跟踪或更新数据,有点 类似 计算属性
实现类似计算属性
<template>
  <div>
    <div>
      <button @click="changeMsg2">修改msg2</button>
      <div>msg2 -- {{ msg2 }}</div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { customRef } from 'vue'
function myRef<T>(value: T) {
  return customRef((trank, trigger) => {
    return {
      get() {
        trank() // 收集依赖
        return value
      },
      set(newVal: T) {
        console.log('set')
        value = newVal
        trigger() // 触发更新
      },
    }
  })
}
let msg2 = myRef<String>('菜鸡')
const changeMsg2 = () => {
  msg2.value = '菜鸡22'
}
</script>
  • 效果
    在这里插入图片描述
封装一个防抖函数
  • 再500毫秒后,再更新这个值
<template>
  <div>
    <div>
      <input v-model="msg2" />
      <div>msg2 -- {{ msg2 }}</div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { customRef } from 'vue'
function useDebouncedRef<T>(value: T, delay: number) {
  let timer: any = null
  return customRef<T>((track, trigger) => ({
    get() {
      track()
      return value
    },
    set(newValue) {
      clearTimeout(timer)
      timer = setTimeout(() => {
        value = newValue
        // ...do something
        trigger()
      }, delay)
    },
  }))
}

const msg2 = useDebouncedRef<string>('0', 500)
</script>

ref 设置获取dom节点

    <div>
      <div ref="aaa">我是aaa的dom节点</div>
      <button @click="getDom">获取don</button>
    </div>

const aaa = ref<HTMLDivElement>()
onMounted(() => {
  console.log('aaa', aaa.value?.innerText)
})

const getDom = () => {
  console.log('aaa222', aaa.value?.innerText)
}

在这里插入图片描述

Logo

前往低代码交流专区

更多推荐