uni-app的setup语法糖需加lang="ts"才能自动解包ref,否则模板中须写count.value;生命周期需用onLoad等函数显式注册;API如navigateTo必须import导入,不可直接调用。

uni-app 的 setup 语法糖不是 Vue 3 原生的 setup,它依赖编译器转换,且只在 .vue 单文件组件中生效,不能直接在 JS/TS 文件里写。
为什么 setup 语法糖在 uni-app 里要加 lang="ts" 才能用响应式?
uni-app 的 setup 语法糖(<script setup>)底层靠 @dcloudio/uni-cli 插件做 AST 转换。不加 lang="ts" 时,插件默认按 JS 处理,ref、computed 等不会自动解包,模板里得写 count.value;加了 lang="ts" 后,插件才启用类型推导和响应式解包逻辑。
- 不加
lang="ts":模板中必须写{{ count.value }},否则显示[object Object] - 加了
lang="ts":模板中可直接写{{ count }},ref自动解包 - 即使你不用 TypeScript,也建议强制加
lang="ts",否则响应式变量在模板里“看起来没反应”
onLoad 和 onShow 这类生命周期怎么在 <script setup> 里注册?
uni-app 的页面生命周期钩子不能直接当普通函数调用,必须通过 onLoad、onShow 等具名函数显式注册,且只能在 <script setup> 顶层调用。
- ✅ 正确写法:
onLoad(() => { console.log('页面加载') }) - ❌ 错误写法:
const onLoad = () => { ... }(这只会覆盖全局onLoad函数,不注册钩子) - ⚠️ 注意:这些钩子只对当前页面组件有效,不能在
defineComponent或子组件里调用 - 多个同名钩子会叠加执行,比如两个
onLoad都会触发
为什么 uni.navigateTo 在 <script setup> 里调用报错 “not defined”?
因为 uni 不是全局变量,而是运行时注入的 API 对象,在 <script setup> 中需显式导入才能使用,否则打包后可能被摇树或作用域隔离导致找不到。
- 必须写:
import { uni } from '@dcloudio/uni-app'或更常用的是直接导入方法:import { uniNavigateTo } from '@dcloudio/uni-app' - 但注意:官方推荐写法是
import { navigateTo } from '@dcloudio/uni-app'(去掉uni前缀),这是 uni-app 3.0+ 的标准导出方式 - 常见错误:
navigateTo({ url: '/pages/home/home' })报ReferenceError: navigateTo is not defined,就是漏了 import - 别用
window.uni.navigateTo—— H5 可能存在,但小程序、App 平台不保证window.uni可用
真正容易卡住的地方,是以为 <script setup> 和 Vue 3 完全一致,结果生命周期、API 导入、响应式解包规则都受 uni-app 编译链约束——它不是语法糖,是一套带平台语义的转译规则。写之前先确认你用的 @dcloudio/uni-cli 版本是否支持(v3.6.12+ 稳定支持),旧版本会静默降级为普通 setup 函数。










