vue3之定义数据(Ref全家桶)
目录vue3之定义数据只是用于展示的数据(非响应式数据)响应式数据 (Ref全家桶)定义简单数据类型判断是否为 ref对象(定义为响应式数据对象)shallowRef 定义简单数据类型的响应式customRef实现类似计算属性封装一个防抖函数vue3之定义数据只是用于展示的数据(非响应式数据)常规的定义变量,这是不具有响应式的,也就是无法更改当前的试图的值<template><d
·
目录
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)
}
更多推荐
已为社区贡献18条内容
所有评论(0)