尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

uni-app x Android VDOM 模式开发实战:从弱类型 JS 到强类型 UTS 的类型体系迁移指南

发布时间:2026/9/19 21:06:23

资讯中心
01
ARTICLE

uni-app x Android VDOM 模式开发实战:从弱类型 JS 到强类型 UTS 的类型体系迁移指南

uni-app x Android VDOM 模式开发实战:从弱类型 JS 到强类型 UTS 的类型体系迁移指南
示例工程前端移动开发跨平台【免费下载链接】uni-appA cross-platform framework using Vue.js项目地址https://gitcode.com/gh_mirrors/un/uni-app点击查看免费下载本文以 docs/tutorial/codegap.md 为骨架整理而成。原文档成文于 DCloud 尚未主推蒸汽模式Vapor的阶段文档开头已明确标注在 DCloud 主推蒸汽模式后本文档已经过期——即其中描述的强类型硬性约束主要针对 Android VDOM 模式下的页面与 uts 插件代码。蒸汽模式页面已放宽联网等场景的类型要求见 Android VDOM 模式下的联网教程 的说明。但理解 uts 的类型体系对编写任何 uni-app x 代码无论 VDOM 还是蒸汽模式仍是基础功课因此本文保留原文档全部核心内容并补充仓库源码佐证供从 uni-app/Web 开发迁移到 uni-app x 的开发者系统学习。引言uni-app x 与 Web 开发最大的差异与 Web 开发相比uni-app x 在 Android 平台 VDOM 模式下最大的变化是弱类型的 js 改为了强类型的 uts。这一变化会深刻影响你的编码习惯变量、方法、参数、返回值、data数据都必须有类型不同类型之间不能随意赋值、比较、运算事件回调如TouchEvent、SwitchChangeEvent必须显式声明参数类型JSON 数据不能像 js 那样随意用.操作符访问需要type或UTSJSONObject两种方案之一。好消息是编译器具备一定的自动推导能力可以帮你补齐相当一部分类型。读懂本文你将掌握 uni-app x 中类型声明、事件参数类型、JSON 处理、编译器类型优化等一整套实战写法避免最常见的编译报错。一、类型系统注意所有数据都必须有类型强类型语言中变量、方法、参数、返回值、data数据都必须有类型。基础类型包括boolean、string、number、Array、Date、UTSJSONObject、any、null等。完整定义与用法需要阅读 uts 类型文档。下面的代码比较典型地说明了 uni-app x 中 uts 类型的要求template view touchstarttouchstart text classred{{s1}}/text /view button clickbuttonClick :disabledbuttonEnable按钮/button /template script languts type User { name:string } //定义一个User类型 export default { data() { const date new Date() //自动推导类型为Date const v 1; //自动推导为number return { buttonEnable: false, //自动推导为boolean s1 : hello, // 根据字面量推导为string n1 : 0 as number, // 这里其实可以根据字面量自动推导as number写不写都行 n2, // 不合法必须指定类型。真实运行时请删掉本行 n3 as number, // 不合法uts不支持undefined必须初始化。真实运行时请删掉本行 n4 : null as number | null // 合法。定义为可为null的数字初始值是null但在使用n4前必须为其赋值数字 year: date.getFullYear() as number, // 在data里目前无法通过变量类型推导data项的类型需使用 as 显式声明 t: , // 模板字面量推导为 string o: { id: 1, name:DCloud }, // 对象字面量推导为 UTSJSONObject注意访问 data 中定义的UTSJSONObject属性时需要使用索引访问如 this.o[id] an: [1, 2], // 数组字面量如果元素均为纯数字字面量则推导为 Arraynumber as: [1, 2, 3], // 数组字面量如果元素均为纯字符串或模板字符串字面量则推导为 Arraystring ab: [true, false], // 数组字面量如果元素均为boolean字面量则推导为 Arrayboolean ao: [{ id: 1 }, { id: 2 }], // 数组字面量如果元素均为对象字面量则推导为 ArrayUTSJSONObject am: [[1, 2], [2, 3], [3, 4]], // 数组字面量支持嵌套推导推导为 ArrayArraynumber aa: [1, 2], // 数组字面量如果元素类型不一致则推导为 Arrayany|null u: { name: DCloud } as User, // 类型断言如果主动指定了类型则不做自动推导使用指定的类型注意自定义type需要定义在 export default 外部或通过其他文件导入 au: [{ name: DCloud }] as User[], // 类型断言支持数组类型断言 v: v, // 非字面量类型目前未指定类型断言推导为 any | null建议此情况均通过as手动指定类型 } } methods: { touchstart(e : TouchEvent) { // e必须有类型 let sX:number e.touches[0].screenX; let sY:number e.touches[0].screenY; }, buttonClick: function () { // 如果不需要 event 参数可以省略 this.buttonEnable true this.s1 点过按钮了 }, } } /script style .red{ color:red } /style这段代码说明了几件事template 和 css 的写法和以前的 uni-app 相同变化集中在 script 区域。data中无法通过:定义类型:在对象字面量里是赋值语义所以 data 数据只有两种处理方式通过字面量自动推导如buttonEnable: false推导为boolean、s1: hello推导为string、an: [1, 2]推导为Arraynumber通过as类型断言显式声明如n4: null as number | null、u: { name: DCloud } as User。自定义type需要定义在export default外部或通过其他文件导入。组件事件参数如TouchEvent必须有类型否则无法访问e.touches[0].screenX。uts不支持undefined任何变量定义后都必须初始化示例中n2、n3即为不合法写法真实运行时需要删除。1.1 自动推导的边界什么场景必须写as从上述示例可以总结出需要显式as的典型场景场景示例说明可为 null 的联合类型n4 : null as number \| null声明可为 null但使用前必须先赋值数字引用非字面量变量v: v非字面量类型默认推导为any \| null建议as手动指定data 中引用变量推导year: date.getFullYear() as numberdata 里无法通过变量类型推导 data 项类型需as自定义 type 对象u: { name: DCloud } as User主动指定类型后不再自动推导数组类型断言au: [{ name: DCloud }] as User[]支持数组形式断言元素类型不一致的数组aa: [1, 2]推导为Arrayany\|null需要按需处理1.2 数组与对象字面量的推导细节元素均为纯数字字面量→Arraynumber均为纯字符串或模板字符串字面量→Arraystring均为boolean 字面量→Arrayboolean均为对象字面量→ArrayUTSJSONObject。支持嵌套推导[[1,2],[2,3],[3,4]]→ArrayArraynumber。元素类型不一致时退化为Arrayany|null。访问 data 中UTSJSONObject类型的属性时需要使用索引访问如this.o[id]而不是.o.id。二、不同类型不能赋值、比较、运算在 js 里可以字符串与数字相加if()里比较一个非 bool 值这些在 uts 里都不行//js let a abc a1 //a的类型从字符串变成了数字。但uts里不能这样 if(a){ //a在js里作为数字被隐式转换为了true。但uts里不能这样如果要判断这个变量是否为nulluts里只能写 if (a!null) }变量a一旦被推导为string就不能再赋number值——强类型下类型是固定的if(a)这种隐式真值判断在 uts 中不合法判断变量是否为 null只能显式写if (a ! null)。这也是从 js 迁移过来最容易踩的坑编译期会直接报错提示。三、全局属性uni 对象与 app.config.globalPropertiesuni-app x中uni对象不支持动态绑定自定义属性且 app.config.globalProperties 暂时不支持。如果你有全局属性的需求例如全局的用户信息、公共配置官方给出的替代方案是使用**全局变量与状态管理**实现——通过 uts 模块导出全局变量或使用状态管理机制在页面间共享数据。四、函数 event 参数的类型上面例子中touchstart事件必须对e指定类型才能使用e.touches[0].screenX。再举一个例子加深记忆template switch changeswitchChange / /template script setup languts const switchChange (e : SwitchChangeEvent) { // 这里必须声明e的类型为SwitchChangeEvent console.log(switch 发生 change 事件携带值为, e.detail.value) } /script那么 event 参数的类型从哪里获取呢有两个途径组件文档中有介绍。以 switch 为例见 switch 组件文档其change事件的类型签名是(event: UniSwitchChangeEvent) voidUniSwitchChangeEvent继承自UniCustomEventUniSwitchChangeEventDetail而UniSwitchChangeEventDetail只有一个必填属性value: boolean。因此e.detail.value是 boolean 类型可以直接用于:checked等布尔绑定。IDE 中有提示鼠标移到 switch 组件的change上悬浮 hover 会显示(property) change: (event: SwitchChangeEvent) void。另外模板中内联函数也可以声明事件类型写法如下view click(e: any) foo(e)event must has type/view view clickfoo($event as MouseEvent)event must has type/view第一种用内联箭头函数参数e声明为any第二种直接调用函数用$event as MouseEvent断言。五、函数参数类型基础类型可省略自定义类型必须指定如果函数参数是基础数据类型函数调用时参数类型可以省略编译器会自动推导如果函数参数是自定义数据类型则必须指定类型// 基础数据类型 function foo1(a: string, b: number) { console.log(a, b) } foo1(hello, 1) // 自定义数据类型 type Person { name: string age: number } function foo2(p: Person) { console.log(p.name, p.age) } foo2({ name: name, age: 18 } as Person) // 或者 const person: Person { name: name, age: 18 } foo2(person)注意uts 文件或 uts 插件中导入的函数如果参数为自定义数据类型也必须指定类型。例如在页面与 uts 工具文件之间传递对象index.uvuetemplate textindex.uvue/text /template script setup languts import type { Person } from ./utils.uts import { logPersonInfo } from ./utils.uts onReady(() { logPersonInfo({ name: name, age: 18 } as Person) // 或者 const person: Person { name: name, age: 18 } logPersonInfo(person) }) /scriptutils.utsexport type Person { name: string, age: number } export function logPersonInfo(person: Person){ console.log(name: person.name) console.log(age: person.age) }这里import type { Person }用于导入类型import { logPersonInfo }导入函数二者可以并存跨文件使用自定义类型时调用侧的实参仍需通过as Person或提前声明变量来满足类型要求。六、JSON 的类型type 与 UTSJSONObject 两种方案JSON 数据在强类型语言中使用时不能像 js 那样随意。js 中可以这么写var p {name: zhangsan,age: 12} p.age //12但是在强类型语言中如果想要使用p.age那么p必须是一个对象而age则是这个对象的属性必须为p对象、name属性、age属性都定义类型比如name是 stringage是 number。uts 中有 2 种方式使用 json 数据把 json 数据转为 type自定义一个类型声明 json 数据内容中每个属性的类型之后就可以用对象属性的方式.操作符使用 json 数据。详见 uts>// 省略参数 onLoad(() { console.log(onLoad) }) // 省略参数类型 onLoad((options) { console.log(onLoad) })7.2 模板函数的 event 参数可以省略但参数存在则必须有类型template view touchstartonTouchstart clickonClick texttext/text /view /template script setup languts const onTouchstart () { // event 参数可以省略 console.log(onTouchstart) } const onClick (event: MouseEvent) { // event 参数存在必须指定类型 console.log(event) } /script7.3 uni 及 uniCloud API 的 {} 字面量参数可省略类型uni及uniCloudAPI 的{}字面量参数可以省略类型success、fail和complete回调函数及其参数类型也可以省略。以uni.navigateTo为例// 省略 {} 字面量参数类型 uni.navigateTo({ url: test // 省略回调函数 }) uni.navigateTo({ url: test, // 省略回调函数参数类型 success(res){ console.log(res) } })如需获取 API 的参数类型信息可通过鼠标悬浮查看。比如封装uni.request时如果参数从函数外部传入则需要指定参数类型否则无法获取参数类型信息// 封装 function request(options : RequestOptions) { uni.request(options) } // 调用 request({url: https://www.example.com/request} as RequestOptions)如果需要查看更详细的参数类型信息可通过鼠标右键点击转到定义跳转到对应的.d.ts文件查看。原文档附带了 IDE 悬浮查看类型信息与转到定义的截图docs/static/view-API-type-info.png、docs/static/go-to-definition.png本文仓库镜像中未收录这两张截图实际开发时以 HBuilderX / 支持 uts 的 IDE 提示为准。八、uts 不支持 js 的一些功能和特性从 js 迁移到 uts 时以下差异需要特别注意不支持undefined任何变量被定义后都需要赋值函数声明方式不支持作为值传递详见 uts function 文档的作为值传递章节函数表达式方式不支持默认参数详见 uts function 文档的默认参数章节不存在声明提升变量、函数等需要先声明、后使用不可以访问未声明的变量或函数包括自身App-iOS 平台的 uts 插件环境中支持async、await需要HBuilderX 4.31。这些限制直接决定了代码的组织顺序type定义、import、变量声明都要放在使用位置之前。九、调用组件方法easycom 用.非 easycom 用 callMethodjs 中 refs 拿到一个组件后可以直接.出它的方法。但 uts 中只有 easycom 组件可以使用.操作符非 easycom 组件需要使用callMethod()。详见 组件 README 的 methods 章节。这意味着在使用非 easycom如通过显式 import 引入的组件时调用其内部方法不能写成this.$refs.xxx.someMethod()而要改用callMethod的方式与组件通信。十、vue 使用注意API 无需手动 import所有vue公开的API都是不需要import的uni-app x会自动引入。比如不需要写import { ref } from vue;直接在页面中书写ref、computed、watch、onLoad、onReady等即可。更多 vue 用法详见 vue README。这一设计与 Web 端 uni-appVue3 需要显式import { ref } from vue有所不同需要注意区分。十一、css 使用注意uni-app x 中 CSS 的使用也有其平台特性与限制详细说明见 css README。涉及样式兼容性、平台差异处理等内容时应以该文档为准。总结从 Web 开发迁移到 uni-app x 的检查清单类型意识变量、方法参数、返回值、data数据、事件参数——全部先问类型是什么能自动推导的交给编译器推导不了的用as断言data 赋值语义data中:是赋值类型要么靠字面量推导要么靠as声明禁止隐式转换不同基础类型不能互相赋值/比较/运算null 判断显式写if (x ! null)事件参数模板函数 event 参数要么省略要么写完整类型类型来源组件文档 IDE hover 提示JSON 二选一本地/可控数据用type有代码提示联网动态数据可参考 request 教程 的UTSJSONObject与type泛型方案遵守 uts 限制无undefined、无声明提升、函数声明不能作为值传递、函数表达式不支持默认参数组件方法调用easycom 用.非 easycom 用callMethod()vue API 免 import全局属性用全局变量与状态管理替代。值得一提的是随着 DCloud 主推蒸汽模式Vapor上述强类型硬性约束正在逐步放宽例如蒸汽模式页面中联网不再要求强类型见 request 教程 开头说明。但 uts 强类型体系本身仍是 uni-app x 的核心语言基础理解本文内容将让你在 VDOM 插件开发、原生能力封装可参考仓库 examples/hello-uts 与 examples/hello-uvue 中的大量真实示例代码时更加得心应手。赞分享示例工程前端移动开发跨平台【免费下载链接】uni-appA cross-platform framework using Vue.js项目地址https://gitcode.com/gh_mirrors/un/uni-app点击查看免费下载相关推荐uni-app UTS 类型兼容性完整指南从结构化类型到运行时类型保留的跨端实践uni app UTS 类型兼容性完整指南从结构化类型到运行时类型保留的跨端实践 导读 UTS 是 uni app x 的跨端强类型语言最终会编译为 Kot示例工程前端移动开发跨平台uni-app xuts中 uni.request 联网数据的强类型化处理UTSJSONObject 与 type泛型双方案实战uni app xuts中 uni.request 联网数据的强类型化处理UTSJSONObject 与 type泛型双方案实战 在 uni app x示例工程前端移动开发跨平台TensorRT 弱类型到强类型迁移自动化trt-strong-typing-migration 辅助脚本实战指南TensorRT 弱类型到强类型迁移自动化trt strong typing migration 辅助脚本实战指南 本篇技术指南围绕 TensorRT 开源仓人工智能深度学习推理引擎模型优化模型编译创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。