经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » Vue.js » 查看文章
uni-app+vue3+ts项目搭建完整流程
来源:cnblogs  作者:唯之为之  时间:2024/1/10 8:59:43  对本文有异议

项目代码同步更新至码云 uni-vue3-ts-template

开发前准备

利用 uni-app 开发,有两种方法:

  1. 通过 HBuilderX 创建(需安装 HBuilderX 编辑器)
  2. 通过命令行创建(需安装 NodeJS 环境),推荐使用 vscode 编辑器

这里我们使用第2种方法,这两种方法官方都有详细介绍 点击查看官方文档

vscode 安装插件

  1. 安装 Vue3 插件,点击查看官方文档
  • 安装 Vue Language Features (Volar) :Vue3 语法提示插件
  • 安装 TypeScript Vue Plugin (Volar) :Vue3+TS 插件
  • 工作区禁用 Vue2 的 Vetur 插件(Vue3 插件和 Vue2 冲突)
  • 工作区禁用 @builtin typescript 插件(禁用后开启 Vue3 的 TS 托管模式)
  1. 安装 uni-app 开发插件
  • uni-create-view :快速创建 uni-app 页面
  • uni-helper(插件套装,安装一个后会有多个插件) :代码提示
  • uniapp小程序扩展 :鼠标悬停查文档

uni-create-view 插件使用

uni-create-view 安装后,需要修改配置,进入 文件 -> 首选项 -> 设置,按以下选项修改即可
image

uni-create-view 使用方法:
src/pages 下右键,选择 新建uni-app页面,弹出输入框,输入 文件夹名称 页面名称,然后回车
image

生成如下目录文件
image

并且在 src/pages.json 目录下,已将新界面配置进去
image

vscode 项目配置

项目生成后,在项目的根目录进行
新建 .vscode 文件夹,并创建 settings.json 文件:

  1. {
  2. // 在保存时格式化文件
  3. "editor.formatOnSave": true,
  4. // 文件格式化配置
  5. "[vue]": {
  6. "editor.defaultFormatter": "esbenp.prettier-vscode"
  7. },
  8. "[json]": {
  9. "editor.defaultFormatter": "esbenp.prettier-vscode"
  10. },
  11. // 配置语言的文件关联
  12. "files.associations": {
  13. "pages.json": "jsonc", // pages.json 可以写注释
  14. "manifest.json": "jsonc" // manifest.json 可以写注释
  15. }
  16. }

同样,在 .vscode 文件夹内,创建 vue3 模板文件,命名为 vue3-uniapp.code-snippets

  1. {
  2. "vue3+uniapp快速生成模板": {
  3. "scope": "vue",
  4. "prefix": "Vue3",
  5. "body": [
  6. "<script setup lang=\"ts\">",
  7. "$2",
  8. "</script>\n",
  9. "<template>",
  10. "\t<view class=\"\">test</view>",
  11. "</template>\n",
  12. "<style lang=\"scss\"></style>",
  13. "$2"
  14. ],
  15. "description": "vue3+uniapp快速生成模板"
  16. }
  17. }

然后,在空白vue文件中,输入vue3,选择此模板,即可快速生成代码
image

项目初始化

项目创建

拉取 uni-app 官方项目基础架构代码 https://uniapp.dcloud.net.cn/quickstart-cli.html

  1. npx degit dcloudio/uni-preset-vue#vite-ts uni-vue3-ts-shop
  2. cd uni-vue3-ts-shop

或者直接直接克隆国内 gitee 地址,然后修改项目名称,并进入项目根目标

  1. git clone -b vite-ts https://gitee.com/dcloud/uni-preset-vue.git

安装ts扩展

主要是为了增加 uni-app微信小程序nodejs 对ts的支持

  1. npm i -D @uni-helper/uni-app-types miniprogram-api-typings @types/node

修改 tsconfig.json

  1. {
  2. "compilerOptions": {
  3. "ignoreDeprecations": "5.0",
  4. "allowJs": true,
  5. },
  6. "types": ["@dcloudio/types", "miniprogram-api-typings", "@uni-helper/uni-app-types"]
  7. },
  8. "vueCompilerOptions": {
  9. // experimentalRuntimeMode 已废弃,现调整为 nativeTags,请升级 Volar 插件至最新版本
  10. "nativeTags": ["block", "component", "template", "slot"]
  11. }
  12. }

配置环境变量

点我查看官方文档

新增env文件

根目录下新建 .env 文件

  1. VITE_HTTP = https://mock.mengxuegu.com/mock/6598258423a3c638568501db/uniapp_template

使用

获取环境变量

  1. process.env.NODE_ENV // 应用运行的模式,比如vite.config.ts里
  2. import.meta.env.VITE_HTTP // src下的vue文件或其他ts文件里

开启 sourcemap

点我查看官方文档
修改 vite.config.ts 文件:

  1. export default defineConfig({
  2. build: {
  3. // 开发阶段启用源码映射:https://uniapp.dcloud.net.cn/tutorial/migration-to-vue3.html#需主动开启-sourcemap
  4. sourcemap: process.env.NODE_ENV === 'development',
  5. },
  6. plugins: [uni()],
  7. })

统一代码规范

安装 prettier

  1. npm i -D prettier

根目录下新建 .prettierrc.json

  1. {
  2. "singleQuote": true,
  3. "semi": false,
  4. "printWidth": 120,
  5. "trailingComma": "all",
  6. "endOfLine": "auto"
  7. }

安装 eslint

  1. npm i -D eslint eslint-plugin-vue @rushstack/eslint-patch @vue/eslint-config-typescript @vue/eslint-config-prettier

根目录下新建 .eslintrc.js

  1. /* eslint-env node */
  2. require('@rushstack/eslint-patch/modern-module-resolution')
  3. module.exports = {
  4. root: true,
  5. extends: [
  6. 'plugin:vue/vue3-essential',
  7. 'eslint:recommended',
  8. '@vue/eslint-config-typescript',
  9. '@vue/eslint-config-prettier',
  10. ],
  11. // 小程序全局变量
  12. globals: {
  13. uni: true,
  14. wx: true,
  15. WechatMiniprogram: true,
  16. getCurrentPages: true,
  17. getApp: true,
  18. UniApp: true,
  19. UniHelper: true,
  20. App: true,
  21. Page: true,
  22. Component: true,
  23. AnyObject: true,
  24. },
  25. parserOptions: {
  26. ecmaVersion: 'latest',
  27. },
  28. rules: {
  29. 'prettier/prettier': [
  30. 'warn',
  31. {
  32. singleQuote: true,
  33. semi: false,
  34. printWidth: 120,
  35. trailingComma: 'all',
  36. endOfLine: 'auto',
  37. },
  38. ],
  39. 'vue/multi-word-component-names': ['off'],
  40. 'vue/no-setup-props-destructure': ['off'],
  41. 'vue/no-deprecated-html-element-is': ['off'],
  42. '@typescript-eslint/no-unused-vars': ['off'],
  43. },
  44. }

package.json 中新增命令 lint

  1. {
  2. "scripts": {
  3. "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore"
  4. }
  5. }

然后运行 npm run lint,将项目内的文件格式化为 eslint 规定的格式(这个命令可随时运行,以便有新页面/插件加入时,解决代码风格的问题)

规范git提交

非必需,适合多人开发

安装 husky

安装并初始化 husky

  1. npx husky-init

如果是首次安装,会有以下提示,输入 y 回车即可

  1. Need to install the following packages:
  2. husky-init@8.0.0
  3. Ok to proceed? (y)

安装完成后,会多出 .husky 文件夹和 pre-commit 文件

安装 lint-staged

  1. npm i -D lint-staged

安装完成后配置 package.json

  1. {
  2. "script": {
  3. // ... 省略 ...
  4. "lint-staged": "lint-staged"
  5. },
  6. "lint-staged": {
  7. "*.{vue,ts,js}": ["eslint --fix"]
  8. }
  9. }

修改 pre-commit 文件

  1. - npm test
  2. + npm run lint-staged

提交规范

至此,已完成 husky + lint-staged 的配置。之后,每次提交代码,在提交信息前都要加入以下提交类型之一,譬如:feat: 首页新增轮播图

提交字段 说明
feat: 增加新功能
fix: 修复问题/BUG
style: 代码风格相关无影响运行结果的
perf: 优化/性能提升
refactor: 重构
revert: 撤销修改
test: 测试相关
docs: 文档/注释
chore: 依赖更新/脚手架配置修改等
workflow: 工作流改进
ci: 持续集成
types: 类型定义文件更改
wip: 开发中

安装 uni-ui 组件库

非必需,也可使用其他组件库

uni-ui 是DCloud提供的一个跨端ui库,它是基于vue组件的、flex布局的、无dom的跨全端ui框架。查看官方文档

安装 uni-ui 及相关插件

sass sass-loaderuni-ui 的依赖库,@uni-helper/uni-ui-types 是类型声明文件

  1. npm i -D sass sass-loader
  2. npm i @dcloudio/uni-ui
  3. npm i -D @uni-helper/uni-ui-types

修改配置

修改 tsconfig.json,配置类型声明文件

  1. {
  2. "compilerOptions": {
  3. "types": ["@dcloudio/types", "miniprogram-api-typings", "@uni-helper/uni-app-types", "@uni-helper/uni-ui-types"]
  4. }
  5. }

修改 src/pages.json,配置自动导入组件

  1. {
  2. "easycom": {
  3. "autoscan": true,
  4. "custom": {
  5. // uni-ui 规则如下配置
  6. "^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"
  7. }
  8. },
  9. "pages": [
  10. // ……
  11. ]
  12. }

安装配置 pina

安装

pinia-plugin-persistedstate 是持久化 pina 插件

  1. npm i pinia pinia-plugin-persistedstate

使用

src 下新增以下目录和文件

  1. src
  2. ├─stores
  3. ├─modules
  4. └─user.ts
  5. | └─index.ts

user.ts

  1. import { defineStore } from 'pinia'
  2. import { ref } from 'vue'
  3. // 定义 Store
  4. export const useMemberStore = defineStore(
  5. 'user',
  6. () => {
  7. // 用户信息
  8. const userInfo = ref<any>()
  9. // 保存用户信息,登录时使用
  10. const setUserInfo = (val: any) => {
  11. userInfo.value = val
  12. }
  13. // 清理用户信息,退出时使用
  14. const clearUserInfo = () => {
  15. userInfo.value = undefined
  16. }
  17. return {
  18. userInfo,
  19. setUserInfo,
  20. clearUserInfo,
  21. }
  22. },
  23. // TODO: 持久化
  24. {
  25. persist: true,
  26. },
  27. )

index.ts

  1. import { createPinia } from 'pinia'
  2. import persist from 'pinia-plugin-persistedstate'
  3. // 创建 pinia 实例
  4. const pinia = createPinia()
  5. // 使用持久化存储插件
  6. pinia.use(persist)
  7. // 默认导出,给 main.ts 使用
  8. export default pinia
  9. // 模块统一导出
  10. export * from './modules/user'

main.ts

  1. import { createSSRApp } from 'vue'
  2. import pinia from './stores'
  3. import App from './App.vue'
  4. export function createApp() {
  5. const app = createSSRApp(App)
  6. app.use(pinia)
  7. return {
  8. app,
  9. }
  10. }

持久化

插件默认使用 localStorage 实现持久化,小程序端不兼容,需要替换持久化 API。
修改 stores/modules/user.ts

  1. export const useUserStore = defineStore(
  2. 'member',
  3. () => {
  4. //…省略
  5. },
  6. {
  7. // 配置持久化
  8. persist: {
  9. // 调整为兼容多端的API
  10. storage: {
  11. setItem(key, value) {
  12. uni.setStorageSync(key, value)
  13. },
  14. getItem(key) {
  15. return uni.getStorageSync(key)
  16. },
  17. },
  18. },
  19. },
  20. )

封装请求

uniapp 拦截器

uni.addInterceptor 的使用参考 官方文档

src 目录下新建 utils 文件夹,并新建 http.ts 文件

  1. import { useUserStore } from '@/stores'
  2. const baseURL = import.meta.env.VITE_HTTP
  3. // 拦截器配置
  4. const httpInterceptor = {
  5. // 拦截前触发
  6. invoke(options: UniApp.RequestOptions) {
  7. // 非 http 开头需拼接地址
  8. if (!options.url.startsWith('http')) {
  9. options.url = baseURL + options.url
  10. }
  11. options.timeout = 10000
  12. // 添加请求头标识
  13. options.header = {
  14. 'request-client': 'wechart-app',
  15. ...options.header,
  16. }
  17. // 添加 token 请求头标识
  18. const memberStore = useUserStore()
  19. const token = memberStore.userInfo?.token
  20. if (token) {
  21. options.header.Authorization = token
  22. }
  23. },
  24. }
  25. // 拦截 request 请求
  26. uni.addInterceptor('request', httpInterceptor)
  27. // 拦截 uploadFile 文件上传
  28. uni.addInterceptor('uploadFile', httpInterceptor)

由于 uni-app 的响应拦截器对类型支持并不友好,所以我们自行封装响应拦截器,同一个文件,继续

  1. /**
  2. * 请求函数
  3. * @param UniApp.RequestOptions
  4. * @returns Promise
  5. */
  6. // Data类型根据后台返回数据去定义
  7. type Data<T> = {
  8. code: string
  9. msg: string
  10. result: T
  11. }
  12. export const http = <T>(options: UniApp.RequestOptions) => {
  13. return new Promise<Data<T>>((resolve, reject) => {
  14. uni.request({
  15. ...options,
  16. // 响应成功
  17. success(res) {
  18. if (res.statusCode >= 200 && res.statusCode < 300) {
  19. resolve(res.data as Data<T>)
  20. } else if (res.statusCode === 401) {
  21. // 401错误 -> 清理用户信息,跳转到登录页
  22. const userStore = useUserStore()
  23. userStore.clearUserInfo()
  24. uni.navigateTo({ url: '/pages/login' })
  25. reject(res)
  26. } else {
  27. // 其他错误 -> 根据后端错误信息轻提示
  28. uni.showToast({
  29. icon: 'none',
  30. title: (res.data as Data<T>).msg || '请求错误',
  31. })
  32. reject(res)
  33. }
  34. },
  35. // 响应失败
  36. fail(err) {
  37. uni.showToast({
  38. icon: 'none',
  39. title: '网络错误,换个网络试试',
  40. })
  41. reject(err)
  42. },
  43. })
  44. })
  45. }

使用

为了统一API文件,我们在 src 目录下新建 api 文件夹,并新建 user.ts

  1. import { http } from '@/utils/http'
  2. export const getUserInfoAPI = (data: any) => {
  3. return http({
  4. url: '/user/info',
  5. method: 'POST',
  6. data,
  7. })
  8. }

然后在需要的地方调用,比如在 page/my/index.vue 里调用:

  1. <script setup lang="ts">
  2. import { useUserStore } from '@/stores'
  3. import { getUserInfoAPI } from '@/api/user'
  4. const userStore = useUserStore()
  5. const getUserInfo = async () => {
  6. const res = await getUserInfoAPI({ id: 'weizwz' })
  7. console.log(res)
  8. const { result } = res
  9. userStore.setUserInfo(result)
  10. }
  11. </script>
  12. <template>
  13. <view class="">
  14. <view>用户信息: {{ userStore.userInfo }}</view>
  15. <button
  16. @tap="
  17. userStore.setUserInfo({
  18. userName: 'weizwz',
  19. })
  20. "
  21. size="mini"
  22. plain
  23. type="primary"
  24. >
  25. 保存用户信息
  26. </button>
  27. <button @tap="userStore.clearUserInfo()" size="mini" plain type="primary">清理用户信息</button>
  28. <button @tap="getUserInfo()" size="mini" plain type="primary">发送请求</button>
  29. </view>
  30. </template>
  31. <style lang="scss"></style>

效果如下,可以看到已经调用成功:
image

如果调用被拦截的话,请检查微信小程序里的项目设置,然后选中 不检验合法域名、web-view(业务域名)、TLS版本以及HTTPS证书 选项

注意事项

开发区别

uni-app 项目每个页面是一个 .vue 文件,数据绑定及事件处理同 Vue.js 规范:

  1. vue文件中的 div 标签需替换为 view 标签
  2. 属性绑定 src="{ { url }}" 升级成 :src="url"
  3. 事件绑定 bindtap="eventName" 升级成 @tap="eventName"支持()传参
  4. 支持 Vue 常用指令 v-forv-ifv-showv-model

其他补充

  1. 调用接口能力,建议前缀 wx 替换为 uni ,养成好习惯,支持多端开发
  2. <style> 页面样式不需要写 scoped,小程序是多页面应用,页面样式自动隔离
  3. 生命周期分三部分:应用生命周期(小程序),页面生命周期(小程序),组件生命周期(Vue)
  4. 其他参考 uniapp-vue语法 官方文档

文章部分内容来自 小兔鲜儿项目 ,本文主要是在此基础上补全了完整创建此项目的流程和所需的依赖

原文链接:https://www.cnblogs.com/weizwz/p/17952042

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号