uni-app是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、H5、以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉)等多个平台。 使用编辑器HbuilderX开发, 下载地址
为了实现多端兼容,综合考虑编译速度、运行性能等因素,uni-app 约定了如下开发规范:
- 页面文件遵循 Vue 单文件组件 (SFC) 规范
- 组件标签靠近小程序规范,详见uni-app 组件规范
- 接口能力(JS API)靠近微信小程序规范,但需将前缀
wx替换为uni,详见uni-app接口规范 - 数据绑定及事件处理同
Vue.js规范,同时补充了App及页面的生命周期 - 为兼容多端运行,建议使用flex布局进行开发
目录结构
pages.json 文件用来对 uni-app 进行全局配置,决定页面文件的路径、窗口样式、原生的导航栏、底部的原生tabbar 等
manifest.json 文件是应用的配置文件,用于指定应用的名称、图标、权限等。
App.vue是我们的跟组件,所有页面都是在App.vue下进行切换的,是页面入口文件,可以调用应用的生命周期函数。
main.js是我们的项目入口文件,主要作用是初始化vue实例并使用需要的插件。
uni.scss文件的用途是为了方便整体控制应用的风格。比如按钮颜色、边框风格,uni.scss文件里预置了一批scss变量预置。
unpackage 就是打包目录,在这里有各个平台的打包文件
pages 所有的页面存放目录
static 静态资源目录,例如图片等
components 组件存放目录
mainfest.json
此文主要用于开发微信小程序,其他的配置可以暂时不管,选择微信小程序配置
| 配置 | 作用 |
|---|---|
| AppID | 填写刚才在微信公共平台获取注册的 AppID |
| ES6转ES5 | 可以勾选 兼容 |
| 上传代码时样式自动补全 | 可以勾选 自动补全 |
| 上传时自动压缩 | 勾选 压缩代码 |
| 检查安全域名和TLS版本 | 不勾选 方便开发 |
| 位置接口 | 此配置需要 在微信公众平台申请相应的接口 |
| unPush2.0 | 消息推送 需要申请 |
| 开启云端一体安全网络 | 加强安全(暂不演示) |
pages.json
注意:此代码为伪代码,只为示例作用,方便查看属性配置使用 无法运行,需要自行配置需要的属性
pages配置
| pages | 数组第一项表示启动项 相当于首页,每新增一个页面 要在pages数组新增一个对象 |
|---|---|
| path | 文件路径 |
| style | 页面样式 下面为style详细配置 |
| navigationBarTitleText | 导航栏标题文字 |
| navigationBarTextStyle | 导航栏标题颜色,仅支持 black/white |
| navigationBarBackgroundColor | 导航栏背景颜色 |
| backgroundColor | tab 的背景色 |
| navigationStyle | 导航栏样式,仅支持 default/customm,开启 custom 后,所有窗口均无导航栏,如使用自定义导航栏 需要设置custom |
| enablePullDownRefresh | 是否开启下拉刷新 |
| onReachBottomDistance | 页面上拉触底事件触发时距页面底部距离,单位为px |
globalStyle全局配置
用于设置应用的状态栏、导航条、标题、窗口背景色等,如果具体的页面中配置了相应项,则会被覆盖。详细文档
| 属性 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| navigationBarBackgroundColor | HexColor | #F7F7F7 | 导航栏背景颜色(同状态栏背景色) |
| navigationBarTextStyle | String | white | 导航栏标题颜色及状态栏前景颜色,仅支持 black/white |
| navigationBarTitleText | String | 导航栏标题文字内容 | |
| backgroundColor | HexColor | #ffffff | 窗口的背景色 |
| backgroundTextStyle | String | dark | 下拉 loading 的样式,仅支持 dark / light |
| enablePullDownRefresh | Boolean | false | 是否开启下拉刷新,详见页面生命周期。 |
| onReachBottomDistance | Number | 50 | 页面上拉触底事件触发时距页面底部距离,单位只支持px,详见页面生命周期 |
tabBar 配置
| tabBar | 解析 |
|---|---|
| color | tab文字默认颜色 |
| selectedColor | tab选中时的颜色 |
| borderStyle | tab上边框的颜色,仅支持 black/white |
| backgroundColor | tab 的背景色 |
| position | 位置 可选值 bottom、top |
| list | 数组 以下为数组对象详解 |
| pagePath | 页面路径,必须在 pages 中先定义 |
| iconPath | 图片路径,icon 大小限制为40kb,建议尺寸为 81px * 81px,当 postion 为 top 时,此参数无效,不支持网络图片 |
| selectedIconPath | 选中时的图片路径,icon 大小限制为40kb,建议尺寸为 81px * 81px ,当 postion 为 top 时,此参数无效 |
| text | tab 上按钮文字 |
{
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "uni-app",
"backgroundTextStyle": "black",
"enablePullDownRefresh": "false",
"onReachBottomDistance": 50
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8",
"navigationStyle": "default"
},
"tabBar": {
"color": "#7A7E83",
"selectedColor": "#3cc51f",
"borderStyle": "black",
"backgroundColor": "#ffffff",
"position": "bottom",
"list": [{
"pagePath": "pages/component/index",
"iconPath": "static/image/icon_component.png",
"selectedIconPath": "static/image/icon_component_HL.png",
"text": "首页"
}, {
"pagePath": "pages/API/index",
"iconPath": "static/image/icon_API.png",
"selectedIconPath": "static/image/icon_API_HL.png",
"text": "购物车"
}]
}
}
样式
-
rpx 即响应式px,一种根据屏幕宽度自适应的动态单位。以750宽的屏幕为基准,750rpx恰好为屏幕宽度。屏幕变宽,rpx 实际显示效果会等比放大。
-
使用
@import语句可以导入外联样式表,@import后跟需要导入的外联样式表的相对路径,用;表示语句结束 -
支持基本常用的选择器class、id、element等
-
在
uni-app中不能使用*选择器。 -
page相当于body节点 -
定义在 App.vue 中的样式为全局样式,作用于每一个页面。在 pages 目录下 的 vue 文件中定义的样式为局部样式,只作用在对应的页面,并会覆盖 App.vue 中相同的选择器。
-
uni-app支持使用字体图标,使用方式与普通web项目相同,需要注意以下几点:-
字体文件小于 40kb,
uni-app会自动将其转化为 base64 格式; -
字体文件大于等于 40kb, 需开发者自己转换,否则使用将不生效;
-
字体文件的引用路径推荐使用以 ~@ 开头的绝对路径。
@font-face { font-family: test1-icon; src: url('~@/static/iconfont.ttf'); }
-
生命周期
应用生命周期
uni-app 支持如下应用生命周期函数:
| 函数名 | 说明 |
|---|---|
| onLaunch | 当uni-app 初始化完成时触发(全局只触发一次) |
| onShow | 当 uni-app 启动,或从后台进入前台显示 |
| onHide | 当 uni-app 从前台进入后台 |
| onError | 当 uni-app 报错时触发 |
页面生命周期
uni-app 支持如下页面生命周期函数:
| 函数名 | 说明 | 平台差异说明 | 最低版本 |
|---|---|---|---|
| onLoad | 监听页面加载,其参数为上个页面传递的数据,参数类型为Object(用于页面传参),参考示例 | ||
| onShow | 监听页面显示。页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面 | ||
| onReady | 监听页面初次渲染完成。 | ||
| onHide | 监听页面隐藏 | ||
| onUnload | 监听页面卸载 |
下拉与上拉
开启下拉刷新
在uni-app中有两种方式开启下拉刷新
- 需要在
pages.json里,找到的当前页面的pages节点,并在style选项中开启enablePullDownRefresh - 通过调用uni.startPullDownRefresh方法来开启下拉刷新
通过配置文件开启
创建list页面进行演示
<template>
<view>
杭州学科
<view v-for="(item,index) in arr" :key="index">
{{item}}
</view>
</view>
</template>
<script>
export default {
data () {
return {
arr: ['前端','java','ui','大数据']
}
}
}
</script>
<style>
</style>
通过pages.json文件中找到当前页面的pages节点,并在 style 选项中开启 enablePullDownRefresh
{
"path":"pages/list/list",
"style":{
"enablePullDownRefresh": true
}
}
通过API开启
uni.startPullDownRefresh()
监听下拉刷新
通过onPullDownRefresh可以监听到下拉刷新的动作
export default {
data () {
return {
arr: ['前端','java','ui','大数据']
}
},
methods: {
startPull () {
uni.startPullDownRefresh()
}
},
onPullDownRefresh () {
console.log('触发下拉刷新了')
}
}
关闭下拉刷新
uni.stopPullDownRefresh()
停止当前页面下拉刷新。
案例演示
<template>
<view>
<button type="primary" @click="startPull">开启下拉刷新</button>
杭州学科
<view v-for="(item,index) in arr" :key="index">
{{item}}
</view>
</view>
</template>
<script>
export default {
data () {
return {
arr: ['前端','java','ui','大数据']
}
},
methods: {
startPull () {
uni.startPullDownRefresh()
}
},
onPullDownRefresh () {
this.arr = []
setTimeout(()=> {
this.arr = ['前端','java','ui','大数据']
uni.stopPullDownRefresh()
}, 1000);
}
}
</script>
上拉加载
通过在pages.json文件中找到当前页面的pages节点下style中配置onReachBottomDistance可以设置距离底部开启加载的距离,默认为50px
通过onReachBottom监听到触底的行为
<template>
<view>
<button type="primary" @click="startPull">开启下拉刷新</button>
杭州学科
<view v-for="(item,index) in arr" :key="index">
{{item}}
</view>
</view>
</template>
<script>
export default {
data () {
return {
arr: ['前端','java','ui','大数据','前端','java','ui','大数据']
}
},
onReachBottom () {
console.log('触底了')
}
}
</script>
<style>
view{
height: 100px;
line-height: 100px;
}
路由导航
导航跳转
navigator详细文档:文档地址
跳转到普通页面
<navigator url="/pages/about/about" hover-class="navigator-hover">
<button type="default">跳转到关于页面</button>
</navigator>
跳转到tabbar页面
<navigator url="/pages/message/message" open-type="switchTab">
<button type="default">跳转到message页面</button>
</navigator>
编程式导航
利用navigateTo进行导航跳转
保留当前页面,跳转到应用内的某个页面,使用uni.navigateBack可以返回到原页面。
<button type="primary" @click="goAbout">跳转到关于页面</button>
通过navigateTo方法进行跳转到普通页面
goAbout () {
uni.navigateTo({
url: '/pages/about/about',
})
}
通过switchTab跳转到tabbar页面
跳转到tabbar页面
<button type="primary" @click="goMessage">跳转到message页面</button>
通过switchTab方法进行跳转
goMessage () {
uni.switchTab({
url: '/pages/message/message'
})
}
redirectTo进行跳转
关闭当前页面,跳转到应用内的某个页面。
<!-- template -->
<button type="primary" @click="goMessage">跳转到message页面</button>
<!-- js -->
goMessage () {
uni.switchTab({
url: '/pages/message/message'
})
}
通过onUnload测试当前组件确实卸载
onUnload () {
console.log('组件卸载了')
}
导航跳转传递参数
在导航进行跳转到下一个页面的同时,可以给下一个页面传递相应的参数,接收参数的页面可以通过onLoad生命周期进行接收
传递参数的页面
goAbout () {
uni.navigateTo({
url: '/pages/about/about?id=80',
});
}
接收参数的页面
<script>
export default {
onLoad (options) {
console.log(options)
}
}
</script>
网络请求
在uni中可以调用uni.request方法进行请求网络请求
需要注意的是:在小程序中网络相关的 API 在使用前需要配置域名白名单。
发送get请求
<template>
<view>
<button @click="sendGet">发送请求</button>
</view>
</template>
<script>
export default {
methods: {
sendGet () {
uni.request({
url: 'http://localhost:8082/api/getlunbo',
success(res) {
console.log(res)
}
})
}
}
}
</script>
条件编译
条件编译其实是用特殊的注释作为标记,在编译时根据这些特殊的注释,将注释里面的代码编译到不同平台。
条件判断规则
以 #ifdef 或 #ifndef 加 %PLATFORM% 开头,以 #endif 结尾。
完整的判断方式为:
#ifdef %PLATFORM%
此部分为实现对应平台的代码
#endif
参数说明:
#ifdef:if defined 仅在某平台存在 #ifndef:if not defined 除了某平台均存在 %PLATFORM%:平台名称
支持的平台
目前 uni-app 条件编译所支持的平台大概有 24 个,分别如下:
引擎+编译器相关
| 值 | 生效条件 | 值 | 生效条件 |
|---|---|---|---|
| VUE3 | 用于区分 vue2 和 3 | VUE2 | 用于区分 vue2 和 3 |
| UNI-APP-X | 用于区分是否是 uni-app x 项目 | uniVersion | 用于区分编译器的版本 |
APP 相关
| 值 | 生效条件 | 值 | 生效条件 |
|---|---|---|---|
| APP | App | APP-PLUS | 编译为 App 时 |
| APP-PLUS-NVUE 或 APP-NVUE | App nvue 页面 | APP-ANDROID | App Android 平台 |
| APP-IOS | App iOS 平台 |
Web 相关
| 值 | 生效条件 | 值 | 生效条件 |
|---|---|---|---|
| H5 | H5 | WEB | web |
小程序相关
| 值 | 生效条件 | 值 | 生效条件 |
|---|---|---|---|
| MP | 包括所有小程序 | MP-WEIXIN | 微信小程序 |
| MP-ALIPAY | 支付宝小程序 | MP-BAIDU | 百度小程序 |
| MP-TOUTIAO | 抖音小程序 | MP-LARK | 飞书小程序 |
| MP-QQ | QQ 小程序 | MP-KUAISHOU | 快手小程序 |
| MP-JD | 京东小程序 | MP-360 | 360 小程序 |
快应用相关
| 值 | 生效条件 |
|---|---|
| QUICKAPP-WEBVIEW | 包括所有快应用 |
| QUICKAPP-WEBVIEW-UNION | 快应用联盟 |
| QUICKAPP-WEBVIEW-HUAWEI | 快应用华为 |
支持的文件
我们主要可以在以下的文件中使用条件编译,如下所示:
- 主文件:包括 .vue/.nvue/.uvue 文件
- API 文件:包括 .js/.uts 文件
- 样式文件:包括 css 文件和各预编译语言文件,如:.scss、.less、.stylus、.ts、.pug 文件
- 配置文件:pages.json 文件
支持的场景
uni-app 的条件编译能支持以下几种场景,具体如图所示:
API 的条件编译
简言之,同一功能实现,可能有不同的逻辑处理,比如:在 js 文件中,或者在 Vue 文件中的 script 代码中有不同的逻辑处理方式,使用方式如下:
// #ifdef %PLATFORM%
该平台特有的API实现;
// #endif
组件的条件编译
在 template 模版中,可能会在不同的平台展示不同的组件,或者是展示效果不同,或者是在某一平台不需要展示,使用方式如下:
<!-- #ifdef %PLATFORM% -->
该平台特有的组件
<!-- #endif -->
样式的条件编译
在不同的平台下有差异性的样式处理,使用方式如下:
/* #ifdef %PLATFORM% */
该平台特有的样式
/* #endif */
pages.json 的条件编译
不同平台下的特有功能,以及小程序平台的分包,都可以通过 pages.json 的条件编译来更好地实现。这样,就不会在其它平台产生多余的资源,进而减小包体积。
例如:在 pages.json 中配置 pages 页面路由,在 H5 平台下编译 “测试 1” 页面,在微信小程序页面下编译 “测试 2” 页面
"pages": [
// #ifdef H5
{
"path": "pages/test1",
"style": {
"navigationBarTitleText": "测试1"
}
},
// #endif
// #ifdef MP-WEIXIN
{
"path": "pages/test2",
"style": {
"navigationBarTitleText": "测试2"
}
},
// #endif
]
特别注意:json 的条件编译,一定要注意最后","分隔符的所属问题,不能有多余的逗号,可能会出现异常情况,导致编译失败!
static 目录的条件编译
在不同平台,引用的静态资源可能也存在差异,通过 static 的条件编译可以解决此问题,static 目录下新建不同平台的专有目录,目录名称均为小写,专有目录下的静态资源只有在特定平台才会编译进去。
如以下目录结构,a.png 只有在微信小程序平台才会编译进去,b.png 在所有平台都会被编译,合理的利用 static 目录的条件编译能够大大的减小包体积,在微信小程序的分包实践中尤为重要!
┌─static
│ ├─mp-weixin
│ │ └─a.png
│ └─b.png
├─main.js
├─App.vue
├─manifest.json
└─pages.json
注意事项
关于条件编译,有以下几个注意事项需要在编程的过程中重点关注一下:
- 条件编译是利用注释实现的,在不同语法里注释写法不一样,不要使用错误的注释编写代码,可能会造成一些问题,具体注释形式如下所示:
- 在 js/uts 文件中, 使用
//注释 - 在 css 文件中, 使用
/* */注释 - 在 vue/nvue/uvue 模板里使用
<!-- 注释 -->
- 条件编译 APP-PLUS 包含 APP-NVUE 和 APP-VUE ;
- 对于未定义平台名称,可能是名称写错了,也可能是低版本 HBuilderX 没有这个平台,此时的条件编译,
#ifdef中的代码不会生效,而#ifndef中的代码会生效; - 使用条件编译请保证编译前和编译后文件的语法正确性,即要保障无论条件编译是否生效都能通过语法校验。比如:json 文件中不能有多余的逗号,js 中不能重复导入;
- Android 和 iOS 平台不支持通过条件编译来区分,如果需要区分 Android、iOS 平台,请通过调用
uni.getSystemInfo来获取平台信息。支持ifios、ifAndroid代码块,可方便编写判断。
状态管理
vuex和pinia
和其他vue项目类似
uni.storage
这块看下对应api的具体用法,这个状态数据是持久化的,除非你调用它的清除接口,这个数据会一直缓存在本地。
globalData
这个用的比较少,这是在app.vue页面定义全局变量,具体用法如下:
<script>
export default {
globalData: {
text: 'text'
}
}
</script>
//在其他页面调用/修改全局变量
getApp().globalData.text = 'test'
全局事件
uniapp有全局事件,这让全局传数据方便不少,阅读本文可同时参考官方文档
uni.$emit
uni.$emit(eventName, OBJECT) 触发全局的自定事件。附加参数都会传给监听器回调。
示例
uni.$emit('update',{msg:'页面更新'});
//或者参数部分随意设置
uni.$emit('aaa','111');
uni.$emit 跨页面传值
// pages/index/index.vue页面
<template>
<view>
<view @tap="clickView">这是index</view>
<view @tap="gotoTest">跳转到test</view>
</view>
</template>
<script>
export default {
onLoad() {
//这里可以用uni.$on/uni.$once监听拿到数据
},
onShow() {
//这里可以用uni.$on/uni.$once监听拿到数据
},
onUnload() {
//移除所有的事件监听器
uni.$off();
},
methods: {
gotoTest() {
uni.$on('on1', this.callback) //注意这里的回调方法后面没有括号
uni.$on('on2', this.callback)
// 跳转到test.vue页面再调用clickTest_emit方法不会触发下面的跳转,只会触发uni.$on/uni.$once
uni.navigateTo({
url: '/pages/test/test'
})
},
clickView() {
// 跳转到test.vue页面再调用clickTest_emit方法不会触发下面的console.log,只会触发uni.$on/uni.$once
console.log('点击了index');
//这个方法被点击调用后可以用uni.$on/uni.$once监听拿到数据
uni.$on('on2', this.callback)
},
aaa() {
//这里可以不用uni.$on/uni.$once监听拿到数据,因为这个方法没有被调用
},
callback(e) {
// 抽离出来的uni.$on回调方法
console.log(e);
}
}
}
</script>
=====================================================================================================================
// pages/test/test.vue页面
<template>
<view @tap="clickTest_emit">这是test_emit</view>
</template>
<script>
export default {
methods: {
clickTest_emit() {
console.log("点击了test_emit");
uni.$emit('on1', '111');
uni.$emit('on2', '222');
uni.$emit('on3', '333');
},
}
}
</script>
uni.$on
uni.$on(eventName,callback) 监听全局的自定义事件。事件可以由 uni.off 使用)
示例
uni.$on('update',function(data){
console.log('监听到事件来自 update ,携带参数 msg 为:' + data.msg);
})
//或者
uni.$on('aaa',(e)=>{
console.log(e);
});
注意所有的 uni.$on 都必须有 uni.$off 结束监听
uni.$once
uni.$once(eventName,callback) 监听全局的自定义事件。事件可以由 uni.$emit 触发,但是只触发一次,在第一次触发之后移除监听器。
示例
uni.$once('update',function(data){
console.log('监听到事件来自 update ,携带参数 msg 为:' + data.msg);
})
//或者
uni.$once('aaa',(e)=>{
console.log(e);
});
uni.$off
uni.$off(eventName,callback) 移除全局自定义事件监听器。(一般配合 uni.$on 使用)
- 如果没有提供参数(没有eventName),则移除所有的事件监听器;
- 如果只提供了事件(只有eventName),则移除该事件所有的监听器;
- 如果同时提供了事件与回调(eventName和callback都有),则只移除这个回调的监听器;
- 提供的回调必须跟 uni.$on 的回调为同一个才能移除这个回调的监听器; 示例
uni.$off('update',function(){
//注意这里的回调方法需要和uni.$on的回调方法保持同一个
})
//或者
uni.$off(['aaa','update'],(e)=>{
//注意这里的回调方法需要和所有uni.$on的回调方法保持同一个(所有uni.$on都用同一个callback方法,看下面的示例)
});
在调用 uni.$off 时,最好根据不同的情况去移除对 uni.$on 的使用。
<template>
<view>
<view>这是index</view>
<view @tap="gotoTest">跳转到test</view>
<view @tap="cancel">取消一个监听</view>
<view @tap="cancelAll">取消多个监听</view>
</view>
</template>
<script>
export default {
methods: {
gotoTest() {
//监听一
uni.$on('on1', this.callback)
//监听二
uni.$on('on2', this.callback)
//监听三
uni.$on('on2', (e) => {
console.log(2, e);
})
console.log('跳转到test');
uni.navigateTo({
url: '/pages/test/test'
})
},
cancel() {
console.log('取消一个监听');
uni.$off('on1', this.callback);
},
cancelAll() {
console.log('取消多个监听');
// 没有提供参数,移除所有的事件监听器(移除全部监听)
// uni.$off();
// 只提供了事件,移除该事件所有的监听器(移除该事件全部监听)
// 单个:uni.$off('on2')
// 多个:uni.$off(['on1', 'on2'])
// 同时提供了事件与回调,只移除这个回调的监听器(只移除该事件的callback回调方法的监听,on1/on2事件还保留。)
// 单个:uni.$off('on2', this.callback),这会移除监听二uni.$on('on2', this.callback)里面的this.callback
// 的监听,不会对监听三uni.$on('on2', (e) => {})里面造成任何影响,下同
// 多个:uni.$off(['on1', 'on2'], this.callback)
// 提供的回调必须跟$on的回调为同一个才能移除这个回调的监听器(就是要把回调方法抽离出来【本文的做法】)
},
callback(e) {
console.log(e);
}
}
}
</script>
=====================================================================================================================
// pages/test/test.vue页面
<template>
<view @tap="clickTest_emit">这是test_emit</view>
</template>
<script>
export default {
methods: {
clickTest_emit() {
console.log("点击了test_emit");
uni.$emit('on1', '111');
uni.$emit('on2', '222');
uni.$emit('on3', '333');
},
}
}
</script>
注意: uni.$emit、 uni.$on 、 uni.$once 、uni.$off 触发的事件都是 App 全局级别的,跨任意组件、页面、nvue、vue 等。使用时,注意及时销毁事件监听,比如,页面 onLoad 里边 uni.on 注册监听,onUnload 里边 uni.\off 移除,或者一次性的事件,直接使用 uni.$once 监听
组件库
uview 官网
特点:生态完善,主要对标vue2技术栈
uview-plus 官网
特点:生态完善,主要对标vue3技术栈,为 uview 的升级版
thorui 官网
特点:组件选项类别丰富,主要对标vue2技术栈,vue3版本组件需要收费
Wot Design Uni 官网
特点:组件选项类别丰富,主要对标vue3技术栈,UI视图风格新颖
UxFrame 官网
特点:组件选项类别丰富,主要对标uni-app x和vue3技术栈,UI视图风格新颖点击了解=》uni-app x
TMUI2.0 官网
特点:组件选项类别丰富,主要对标vue2技术栈,已暂停维护
TMUI3.0 官网
特点:组件选项类别丰富,主要对标vue3技术栈,UI视图风格新颖
t-uvue-ui 官网
特点:主要对标uni-app x和vue3技术栈,UI视图风格新颖点击了解=》uni-app x
wxui 官网
特点:主要对标uni-app x和vue3技术栈,UI视图风格新颖点击了解=》uni-app x
easyx 官网
特点:组件选项类别丰富,主要对标uni-app x和vue3技术栈,UI视图风格新颖点击了解=》uni-app x
Grace 官网
特点:组件选项类别丰富UI视图风格新颖,部分组件为收费
Tuniao UI 官网
特点:组件选项类别丰富UI视图风格新颖,主要对标vue2技术栈
Tuniao UI V3 官网
特点:组件选项类别丰富UI视图风格新颖,主要对标vue3技术栈
SinleUI 官网
专为跨平台框架
uni-app x开发