useId
为 每一个 vue 文件创建一个唯一的 id:
app.vue
import {useId} from "vue";
import Child from "@/Child.vue";
const comId = useId();
console.log("=>(App.vue:5) comId", comId);
// ...
<Child />
但是这样说其实并不准确,它只会对一个 createApp 的实例生成一个唯一的 id,而如果存在多个 createApp ,那么每一个 createaApp 的实例中的 id 其实都是相同的,所以这时候我们可以选择自定义一个唯一的前缀+ id,进行二次 id 的单一化。
app1.config.idPrefix = 'app1 -';
useTemplateRef
useTemplateRef 是对 ref 对 dom 获取或者组件实例的一个改动,以便区分使用 ref 获取响应式数据和 dom。
<script setup>
import {onMounted, useTemplateRef} from "vue";
const myDom = useTemplateRef('dom1')
onMounted(() => {
console.log(myDom.value)
})
</script>
<template>
<div ref="dom1">1111</div>
</template>
解构的数据还具有响应式
<script setup>
import {ref} from "vue";
import Child from "@/Child.vue";
const data = ref(0)
const addData = () => {
data.value++
}
</script>
<template>
<Child :data="data"></Child>
<button @click="addData()">addData</button>
</template>
<script setup>
// 解构的数据只读且具有响应式
import {watchEffect} from "vue";
const {data} = defineProps(['data'])
console.log("=>(Child.vue:7) data", data);
watchEffect(() => {
console.log("=>(Child.vue:9) data", data);
})
</script>
<template>
{{data}}
</template>
如果不想使用该功能,也可以在 vite.config.js 中关闭:
而且还可以直接设置默认值了:
const {data = 0} = defineProps<{
data?: number
}>()
之前我们设置默认值需要 withDefault。
当然,和之前一样,还是不可以直接使用 watch 监听传递过来的响应式数据,需要使用使用一个函数返回:
watch(() => data, () => {
console.log('data changed')
})
onWatcherCleanup
用于清除之前 watch 的副作用。
// 写法一
watch(count , (newVal, oldValue) => {
const handle = () => {
console.log('click', newVal)
}
addEventListener('click', handle)
// 清除 watch 的副作用 接收一个回调,会在下次执行 watch 之前执行
// 比如我们这个例子 不清除副作用的话 会在下次点击执行两次点击事件的触发
// (一次之前已经绑定的点击事件,一个刚刚绑定的点击事件)
onWatcherCleanup(() => {
removeEventListener('click', handle)
})
}, {
immediate: true
})
// 写法二
watch(count , (newVal, oldValue, onCleanup) => {
const handle = () => {
console.log('click', newVal)
}
addEventListener('click', handle)
// 清除 watch 的副作用 接收一个回调,会在下次执行 watch 之前执行
// 比如我们这个例子 不清除副作用的话 会在下次点击执行两次点击事件的触发
// (一次之前已经绑定的点击事件,一个刚刚绑定的点击事件)
onCleanup(() => {
removeEventListener('click', handle)
})
}, {
immediate: true
})