1 构建Uniapp
本节参考:
快速上手Uni-app
安装vue脚手架
bash
npm install -g @vue/cli
创建uni-app
bash
npx degit dcloudio/uni-preset-vue#vite my-vue3-project
2 安装Wot Design Uni
本节参考:快速上手WotUI
安装sass依赖
bash
pnpm add sass -D
安装Wot Design Uni
bash
pnpm add wot-design-uni
配置wot组件自动导入:
json
// pages.json
{
"easycom": {
"autoscan": true,
"custom": {
"^wd-(.*)": "wot-design-uni/components/wd-$1/wd-$1.vue"
}
},
// 此为本身已有的内容
"pages": [
// ......
]
}
3 安装UnoCss
本节参考:unocss-preset-uni
bash
pnpm add @uni-helper/unocss-preset-uni -D
# unocss v0.58
pnpm add unocss@0.58.9 unocss-applet@0.7.8 -D
配置vite.config.ts
ts
// vite.config.ts,支持 HBuilderX
import { defineConfig } from 'vite'
import Uni from '@dcloudio/vite-plugin-uni'
export default async () => {
const UnoCSS = (await import('unocss/vite')).default
return defineConfig({
plugins: [
Uni(),
UnoCSS()
]
})
}
创建uno.config.ts文件
ts
import { presetUni } from '@uni-helper/unocss-preset-uni'
import {
defineConfig,
presetIcons,
transformerDirectives,
transformerVariantGroup,
} from 'unocss'
export default defineConfig({
presets: [
presetUni(),
presetIcons({
scale: 1.2,
warn: true,
extraProperties: {
'display': 'inline-block',
'vertical-align': 'middle',
},
// HBuilderX 必须针对要使用的 Collections 做异步导入
// collections: {
// carbon: () => import('@iconify-json/carbon/icons.json').then(i => i.default),
// },
}),
],
transformers: [
transformerDirectives(),
transformerVariantGroup(),
],
})
main.js
bash
// main.js
import 'uno.css';
配置自动导入
json
// pages.json
{
"easycom": {
"autoscan": true,
"custom": {
"^u-(.*)": "unocss-preset-weapp/components/u-$1.vue"
}
},
// 其他配置
}
4 配置Auto-import
本节参考:unplugin-auto-import
安装依赖:
bash
pnpm add -D unplugin-auto-import
vite.config.ts配置
ts
import AutoImport from 'unplugin-auto-import/vite'
export default defineConfig({
plugins: [
AutoImport({
imports:['vue', 'uni-app'],
dts: 'src/types/auto-imports.d.ts',
dirs: ['src/components', 'src/utils', 'src/store'],
vueTemplate: true,
}),
],
})
5 配置vite-plugin-uni-layouts
安装依赖:
bash
pnpm add -D @uni-helper/vite-plugin-uni-layouts
配置vite.config.ts
ts
// vite.config.ts
import { defineConfig } from 'vite'
import uni from '@dcloudio/vite-plugin-uni'
import UniLayouts from '@uni-helper/vite-plugin-uni-layouts'
export default defineConfig({
plugins: [UniLayouts(), uni()],
})
在src/layouts下创建布局文件:
ts
<!-- default.vue -->
<template>
<slot>main</slot>
</template>
让page页面应用布局:
json
// pages.json
{
// ...
"pages": [{
"path": "pages/index/index",
// 可选, 这是默认值
"layout": "default"
}]
// ...
}
6 配置vite-plugin-uni-manifest
vite-plugin-uni-manifest的作用:用ts/js来管理manifest文件,以后就不要手动修改manifest.json文件了。
安装:
bash
pnpm add -D @uni-helper/vite-plugin-uni-manifest
配置vite.config.ts
ts
// vite.config.ts
import Uni from '@dcloudio/vite-plugin-uni'
import UniManifest from '@uni-helper/vite-plugin-uni-manifest'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [UniManifest(), Uni()],
})
创建manifest.config.ts配置文件来接管manifest.json文件
ts
import { defineManifestConfig } from '@uni-helper/vite-plugin-uni-manifest'
export default defineManifestConfig({
'name': 'uni-app',
'appid': '',
'description': '',
'versionName': '1.0.0',
'versionCode': '100',
'transformPx': false,
'icon': 'static/logo.png',
'launchIcon': 'static/logo.png',
'launchImage': 'static/logo.png',
'launchMode': 'standard',
'launchTimeout': 3000,
/* 5+App特有相关 */
'app-plus': {
usingComponents: true,
nvueStyleCompiler: 'uni-app',
compilerVersion: 3,
splashscreen: {
alwaysShowBeforeRender: true,
waiting: true,
autoclose: true,
delay: 0,
},
/* 模块配置 */
modules: {},
/* 应用发布信息 */
distribute: {
/* android打包配置 */
android: {
permissions: [
'<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>',
'<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>',
'<uses-permission android:name="android.permission.VIBRATE"/>',
'<uses-permission android:name="android.permission.READ_LOGS"/>',
'<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>',
'<uses-feature android:name="android.hardware.camera.autofocus"/>',
'<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>',
'<uses-permission android:name="android.permission.CAMERA"/>',
'<uses-permission android:name="android.permission.GET_ACCOUNTS"/>',
'<uses-permission android:name="android.permission.READ_PHONE_STATE"/>',
'<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>',
'<uses-permission android:name="android.permission.WAKE_LOCK"/>',
'<uses-permission android:name="android.permission.FLASHLIGHT"/>',
'<uses-feature android:name="android.hardware.camera"/>',
'<uses-permission android:name="android.permission.WRITE_SETTINGS"/>',
],
},
/* ios打包配置 */
ios: {},
/* SDK配置 */
sdkConfigs: {},
/* 图标配置 */
icons: {
android: {},
ios: {},
},
},
},
/* 快应用特有相关 */
'quickapp': {},
/* 小程序特有相关 */
'mp-weixin': {
appid: '',
setting: {
urlCheck: false,
},
usingComponents: true,
},
'mp-alipay': {
usingComponents: true,
},
'mp-baidu': {
usingComponents: true,
},
'mp-toutiao': {
usingComponents: true,
},
'uniStatistics': {
enable: false,
},
'vueVersion': '3',
})
7 配置vite-plugin-uni-pages
vite-plugin-uni-pages主要是用来接管pages.json文件的,也就是说以后可以用ts或js来管理页面路由,另外也可以配置路由元数据来实现路由守卫,比如
html
<!-- pages/user/profile.vue -->
<route>
{
meta: {
requiresAuth: true,
roles: ['user']
}
}
</route>
ts
// hooks/useRouteGuard.ts
uni.addInterceptor('navigateTo', {
invoke(params) {
// 获取路由元数据
const meta = 页面元数据
if (meta.requiresAuth && !isLoggedIn()) {
// 拦截跳转,重定向到登录页
uni.navigateTo({ url: '/pages/login/login' })
return false
}
return true
}
})
安装
bash
pnpm i -D @uni-helper/vite-plugin-uni-pages
配置vite.config.ts文件:
ts
// vite.config.ts
import { defineConfig } from 'vite'
import Uni from '@dcloudio/vite-plugin-uni'
import UniPages from '@uni-helper/vite-plugin-uni-pages'
// It is recommended to put it in front of Uni
export default defineConfig({
plugins: [UniPages(), Uni()],
})
创建pages.config.ts配置文件:
ts
// pages.config.ts
import { defineUniPages } from '@uni-helper/vite-plugin-uni-pages'
export default defineUniPages({
easycom: {
autoscan: true,
custom: {
"^wd-(.*)": "wot-design-uni/components/wd-$1/wd-$1.vue",
"^u-(.*)": "unocss-preset-weapp/components/u-$1.vue"
}
},
pages: [
{
path: 'pages/index/index',
style: {
navigationBarTitleText: '首页',
navigationBarBackgroundColor: '#ff0000',
navigationBarTextStyle: 'black',
},
layout: "default",
}
],
globalStyle: {
navigationBarTextStyle: 'black',
navigationBarTitleText: '@uni-helper',
},
})
现在,所有page都可以被自动发现,你也可以手动设置page的路由,它拥有最高优先级。
通过虚拟块来获取pages.config.ts中的路由数组数据:
ts
<script setup>
import {pages} from 'virtual:uni-pages'
console.log(pages)
// 查找特定页面配置
const indexPage = pages.find(page => page.path === 'pages/index/index')
console.log(indexPage)
// 获取页面总数
console.log(pages.length)
</script>
virtual:uni-pages 是 uni-app 中的一个虚拟模块(Virtual Module)
包含的内容是一个数组:
ts
// pages 数组包含了项目中所有页面的配置信息
[
{
path: 'pages/index/index',
style: {
navigationBarTitleText: '首页'
}
},
{
path: 'pages/about/about',
style: {
navigationBarTitleText: '关于'
}
}
// ... 其他页面配置
]
用法:
先安装uni-mini-router
bash
pnpm add -D uni-mini-router
注册路由:
src/internal/initialize/router/index.js
ts
import { pages, subPackages } from 'virtual:uni-pages'
import {createRouter} from 'uni-mini-router'
function generateRoutes() {
const routes = pages.map((page) => {
const newPath = `/${page.path}`
return { ...page, path: newPath }
})
if (subPackages && subPackages.length > 0) {
subPackages.forEach((subPackage) => {
const subRoutes = subPackage.pages.map((page) => {
const newPath = `/${subPackage.root}/${page.path}`
return { ...page, path: newPath }
})
routes.push(...subRoutes)
})
}
return routes
}
const router = createRouter({
routes: generateRoutes(),
})
router.beforeEach((to, from, next) => {
console.log(to)
console.log(from)
next()
})
router.afterEach((to, from) => {
console.log(to)
console.log(from)
})
export default router
ts
import {
createSSRApp
} from "vue";
import App from "./App.vue";
import router from "./internal/initialize/router";
import 'uno.css';
export function createApp() {
const app = createSSRApp(App);
app.use(router)
return {
app,
};
}
如何使用uni-mini-router
ts
// 页面跳转
router.push('/path')
router.push({ path: '/path', query: { id: 1 }})
// 替换当前页面
router.replace('/path')
// 返回
router.back()
router.go(-1)
// 前进
router.forward()
router.go(1)
比如:
ts
<script setup>
import { useRouter, useRoute } from 'uni-mini-router'
const route = useRoute()
console.log(route.path) // 当前路径 /pages/index/index
console.log(route.fullPath) // 完整路径 /
console.log(route.query) // 查询参数 {} /pages/user/detail?id=123 query就是 { id: '123' }
console.log(route.params) // 路由参数 {} path: '/pages/user/:id', // :id就是路由参数
console.log(route.meta) // 路由元信息 {requireAuth: true}
const router = useRouter()
// 路由跳转
const goToPage = () => {
router.push('/pages/index/index')
}
// 带参数跳转
const goToDetailPage = () => {
router.push({
path: '/pages/detail/detail',
query: {
id: 1
}
})
}
// 返回上一页
const goBack = () => {
router.back()
}
</script>