vue3.5 重要更新内容 
解构 defineProps 
在 Vue 3.5 之前,defineProps 不能直接解构。如果需要解构,可能会丢失响应式特性。而对于 props 的默认值,则需要配合 withDefaults 使用。
示例代码
父组件代码:
vue
<script setup>
import ChildComp from './ChildComp.vue';
</script>
<template>
  <ChildComp></ChildComp>
</template>子组件代码:
在 3.5 之前需要使用 withDefaults:
vue
<script setup lang="ts">
import { defineProps, withDefaults } from 'vue'
withDefaults(defineProps<{
  type?: 'card' | 'panel'
}>(), {
  type: 'card'
})
</script>
<template>
  <div>
    <!-- 默认显示 card -->
    {{ type }}
  </div>
</template>跳转到 Vue SFC Playground 查看效果。
在 3.5 之后,defineProps 支持直接解构,并且可以设置默认值:
vue
<script setup lang="ts">
import { defineProps } from 'vue'
const { type = 'panel' } = defineProps<{
  type?: 'card' | 'panel'
}>()
// 这样是监听不到的
watch(type, () => {})
// 这样是可以监听到的
watch(() => type, () => {})
</script>
<template>
  <div>
    <!-- 默认显示 panel -->
    {{ type }}
  </div>
</template>跳转到 Vue SFC Palyground 查看效果。
注意
但是通过解构的方式还有个弊端,就是使用 watch 的时候,需要传递一个 getter 才能够被监听。
useId 
Vue 3.5 新增了 useId 方法,用于生成全局唯一的自增 ID。每个组件实例中生成的 ID 是独立的,不会重复。
使用示例
vue
<script setup>
import { useId } from 'vue'
const id = useId()
</script>跨多个应用的唯一性
在同一个 createApp 实例中,useId 保证生成的 ID 是唯一的。如果需要在多个 createApp 实例中确保唯一性,可以通过设置 ID 前缀实现:
ts
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.config.idPrefix = 'app1-'
app.mount('#app')useTemplateRef 
在 Vue 3.5 之前,我们通过 ref 获取 DOM 或组件引用。缺点是:变量名必须与 ref 的值保持一致,且 ref 本身也只是为了声明响应式数据设计的。
传统方式
vue
<script setup lang="ts">
import { ref } from 'vue'
const buttonRef = ref<HTMLButtonElement | null>(null)
console.log(buttonRef.value)
</script>
<template>
  <button ref="buttonRef"></button>
</template>使用 useTemplateRef
Vue 3.5 提供了更灵活的 useTemplateRef 方法,允许自由命名引用变量:
vue
<script setup lang="ts">
import { useTemplateRef } from 'vue'
const buttonEl = useTemplateRef<HTMLButtonElement>('buttonRef')
console.log(buttonEl.value)
</script>
<template>
  <button ref="buttonRef"></button>
</template>onWatcherCleanup 
在 watch 函数触发时,希望做一些清楚副作用的时候很有用,比如下面这样:
方式一
vue
<script setup>
import { watch, ref, onWatcherCleanup } from 'vue'
const num = ref(0)
watch(num, newVal => {
  const handle = () => {
    console.log('click', newVal)
  }
  window.addEventListener('click', handle)
  // 在下次 watch 触发时调用
  onWatcherCleanup(() => {
    window.removeEventListener('click', handle)
  })
})
</script>方式二
vue
<script setup>
import { watch, ref } from 'vue'
const num = ref(0)
watch(num, (newVal, oldVal, onCleanup) => {
  const handle = () => {
    console.log('click', newVal)
  }
  window.addEventListener('click', handle)
  // 在下次 watch 触发时调用
  onCleanup(() => {
    window.removeEventListener('click', handle)
  })
})
</script>隐藏功能:watch 
在 Vue 3.5 中,watch 的深度监听新增了层级限制功能。通过设置 deep 的值,可以指定监听的对象层级深度。
示例代码
vue
<script setup>
import { watch, reactive } from 'vue'
const state = reactive({
  a: {
    b: {
      c: 1
    }
  }
})
watch(
  () => state,
  () => {
    console.log('watch')
  },
  {
    deep: 2
  }
)
</script>watch 的其他隐藏功能看这里 watch的暂停、恢复、停止