【uni-app】市面上的模板一堆?打开源码一看乱的一匹?教你如何定制适合自己的模板

准备工作

使用vue-cli创建,脱离HBuilderX(真的很难用)

uni-app这里选择vue3 + typescript的版本

先把空壳拉下来npx degit dcloudio/uni-preset-vue#vite-ts my-vue3-project

或者通过官网的gitee下载点击下载

1. UI库选择

名称 特点 缺点
uni-ui 高性能,全端覆盖,支持nvue(uniapp官方出品) 丑,封装的太死
ThorUI 组件丰富,全端覆盖(比uni-ui好看) 不支持nvue
uview-plus3.0 组件丰富,支持nvue(比uni-ui好看) 没用过,用的少,不做评价

如果你对ui库的需求不高,大多数都需要手写样式的话(产品要求的100%还原设计图那种),我建议组件库都不需要使用或者使用uni-ui即可

这里选择使用uni-ui作为项目的ui库(也可以自己更换其他的,操作是一样的)

js 复制代码
pnpm install @dcloudio/uni-ui

uni-ui符合easycom规范,添加到src/pages.json即可实现自动引入(easycom规范是什么东西?点击查看

js 复制代码
// src/pages.json
{
  "pages": [
    // 你的页面
  ],
 // 添加以下代码(实现自动引入uni-ui所有组件)
  "easycom": {
    "custom": {
      "^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"
    }
  }
}

如果需要改uni-ui的主题色,或者文字颜色什么的,直接改src/uni.scss,因为uni-ui用的都是里面的变量(改这个文件需要重新编译才可以生效)

2. 组件类型提示

相信大家在写uni-app的时候都有这样的场景

  • 写个banner轮播图,如何改衔接滑动来着?(打开浏览器找文档)
  • 记得组件的某个属性几个字母,也无法拼全和确定自己写的正不正确?(打开浏览器找文档)

以上场景来源于组件没有类型提示而造成的困扰。而 uni-app 官方对于 typeScript 支持只有 @dcloudio/types,它提供了脚本部分的 typeScript 支持,但组件的 TypeScript 一直都没有。此时有一个为 uni-app 打造的 typeScript 支持库出现了@uni-helper/uni-typed

我们只需要关注这几个子包

  • @uni-helper/uni-app-types(为 uni-app 组件提供 TypeScript 类型)
  • @uni-helper/uni-cloud-types(为 uni-cloud 组件提供 TypeScript 类型)
  • @uni-helper/uni-ui-types(为 uni-ui 组件提供 TypeScript 类型)
  • @uni-helper/uni-types(以上三者的集合)

我现在的目标:需要uni-app的内置组件和uni-ui的组件拥有类型提示

我选择@uni-helper/uni-app-types@uni-helper/uni-ui-types进行安装(如果使用uni-cloud和uni-ui的话,可直接安装@uni-helper/uni-types就好了)

js 复制代码
pnpm install @uni-helper/uni-app-types @uni-helper/uni-ui-types

然后打开tsconfig.json

js 复制代码
{
  "compilerOptions": {
    // 你其他配置
    // ...
    
    "types": [
      // 为 vite 提供 TypeScript 类型
      "vite/client",
      // 为 uni-app API 提供 TypeScript 类型
      "@dcloudio/types",
      // 为 uni-app 组件提供 TypeScript 类型
      "@uni-helper/uni-app-types",
      // 为 uni-ui 组件提供 TypeScript 类型
      "@uni-helper/uni-ui-types"
    ]
  },
  "vueCompilerOptions": {
    // Vue - Official 调整解析行为
    "plugins": [
      "@uni-helper/uni-app-types/volar-plugin",
      "@uni-helper/uni-ui-types/volar-plugin"
    ]
  }
}

重启vscode后,此时组件已经变成绿色,证明生效啦。鼠标放上去,描述出现,点击查看组件文档,直接跳转,领导再也不会说你效率低了

然后你输入几个字母,看到提示后,眼泪流了下来,原来swper的衔接活动的属性是circular

搬砖佬:不好意思,我连几个字母都记不住,还不是得打开浏览器去找?

我:也不用,按住ctrl鼠标左键点击组件找到组件props类型更快哦

3. ESLint9

在我认为,eslint在前端应该是必不可少的东西,它能很好的矫正你的代码,以及提前发现你可能没发现的错误语法,使用eslint会使得一定的效率提升上去。

eslint9相比于之前的版本改动很大,掘友应该也看腻了,废话不多说,直接开始。

  • eslint(核心包)
  • eslint-plugin-vue(vue语法支持)
  • @vue/eslint-config-typescript(vue ts支持)
  • @vue/eslint-config-prettier(vue prettier支持)
  • vite-plugin-eslint(vite使用eslint校验代码)
js 复制代码
pnpm install eslint eslint-plugin-vue @vue/eslint-config-typescript @vue/eslint-config-prettier vite-plugin-eslint

根目录新建eslint.config.mjs(eslint用于处理代码语法问题)

js 复制代码
import pluginVue from 'eslint-plugin-vue'
import { defineConfigWithVueTs, vueTsConfigs } from '@vue/eslint-config-typescript'
import prettierConfig from '@vue/eslint-config-prettier'

export default defineConfigWithVueTs(
  pluginVue.configs['flat/recommended'],
  vueTsConfigs.recommended,
  prettierConfig,
  [
    {
      rules: {
        // 在这里改写覆盖规则
        // ...
      }
    }
  ]
)

根目录新建prettier.config.mjs(prettier用于处理代码格式问题)

js 复制代码
export default {
  singleQuote: true,     // 使用单引号
  semi: false,           // 行尾分号
  printWidth: 100,       // 每行代码最大宽度
  trailingComma: 'none', // 尾随逗号
  endOfLine: 'auto'      // 行尾序列
}

配置vite.config.ts

js 复制代码
import { defineConfig } from 'vite'
import uni from '@dcloudio/vite-plugin-uni'
import EslintPlugin from 'vite-plugin-eslint'

export default defineConfig({
  plugins: [
    uni(),
    EslintPlugin()
  ]
})

重启vscode(代码问题一目了然)

鼠标右键编辑区域,选择使用...格式化文档,然后选择ESlint(设置之后,默认快捷键alt+shift+F即可格式化代码)

搬砖佬:让我团队每个人都这样设置一遍太麻烦了,有没有默认就帮他们设置好呢?(有的,在项目里新建.vscode/settings.json文件)

js 复制代码
{
  // 其他配置
  // ...
  
  // 默认格式化eslint
  "[vue]": {
    "editor.defaultFormatter": "dbaeumer.vscode-eslint"
  },
  "[javascript]": {
    "editor.defaultFormatter": "dbaeumer.vscode-eslint"
  },
  "[typescript]": {
    "editor.defaultFormatter": "dbaeumer.vscode-eslint"
  },
  // 保存自动格式化
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit"
  }
}

4. 自动导入

问题一:还有就是请求做了封装,但是每次使用都import吗?这也太累了,用provide/inject来使用请求,但是每个页面都inject也很麻烦,有没有什么好方法呢?

问题二:vue和uni-app的生命周期以及各种函数背得滚瓜烂熟,每次都引入属实降低效率,应该怎么进行自动引入呢?

先说问题一的两种解决方案,一种是直接挂到uni对象上面去,另一种是使用unplugin-auto-import自动导入

方案一(挂到uni对象上-不推荐)

js 复制代码
// src/main.ts
import request from '@/utils/request'

uni.$http = request

搬砖佬:使用是可以使用了,但是没类型提示,很难受啊!

我:别着急,往下看,找到/src/env.d.ts

js 复制代码
/// <reference types="vite/client" />

declare module '*.vue' {
  import { DefineComponent } from 'vue'
  import request from '@/utils/request'

  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
  const component: DefineComponent<{}, {}, any>
  export default component
  
  global {
    // 给Uni对象添加属性
    interface Uni {
      $http: typeof request
    }
  }
}

搬砖佬:是可以了,但是为什么说这种方案不推荐呢?

我:因为这种破坏了uni的对象,万一以后需要升级uniapp版本,并且出了个新的属性和你挂上去的一样,就不好维护了。来看方案二

方案二(自动导入)

js 复制代码
pnpm install unplugin-auto-import

打开vite.config.ts

js 复制代码
import { defineConfig } from 'vite'
import uni from '@dcloudio/vite-plugin-uni'
import EslintPlugin from 'vite-plugin-eslint'
import AutoImport from 'unplugin-auto-import/vite'

export default defineConfig({
  plugins: [
    uni(),
    EslintPlugin(),
    AutoImport({
      imports: [{ '@/utils/request.ts': [['default', 'request']] }]
    })
  ]
})

我:现在,启动项目后会产生auto-imports.d.ts文件,里面就会包含你的request对象。你可以在任何地方直接使用request了。

搬砖佬:没生效啊?

我:查看你的tsconfig.json文件,如果写了include,那需要把auto-imports.d.ts加进去。建议删除include,这样的话会自动排除node_modules的检查,直接检查整个项目的文件

搬砖佬:可以了,也有类型提示,舒服的一匹。

我:说回第二个问题,直接在imports里面添加即可,自带了vue和uni-app的导入。

js 复制代码
import { defineConfig } from 'vite'
import uni from '@dcloudio/vite-plugin-uni'
import EslintPlugin from 'vite-plugin-eslint'
import AutoImport from 'unplugin-auto-import/vite'

export default defineConfig({
  plugins: [
    uni(),
    EslintPlugin(),
    AutoImport({
      imports: [{ 'vue', 'uni-app',  '@/utils/request.ts': [['default', 'request']] }]
    })
  ]
})

5. unocss(可选)

这玩意怎么说呢,有人喜欢有人恨,但是也出个配置的教程吧,也许能帮的上别人呢。

  • unocss(核心包)
  • unocss-preset-weapp(用于兼容小程序)
  • @unocss/transformer-directives(支持@apply)
  • @unocss/transformer-variant-group(支持组写法,如b-(1px solid red))
js 复制代码
pnpm install unocss unocss-preset-weapp @unocss/transformer-directives @unocss/transformer-variant-group

根目录新建uno.config.ts文件

js 复制代码
import { defineConfig } from 'unocss'
import presetWeapp from 'unocss-preset-weapp'
import transformerVariantGroup from '@unocss/transformer-variant-group'
import transformerDirectives from '@unocss/transformer-directives'
import { extractorAttributify, transformerClass } from 'unocss-preset-weapp/transformer'

const { presetWeappAttributify, transformerAttributify } = extractorAttributify()

export default defineConfig({
  presets: [presetWeapp() as any, presetWeappAttributify()],
  transformers: [
    transformerVariantGroup(),
    transformerDirectives(),
    transformerAttributify() as any,
    transformerClass()
  ],
  theme: {
    // 自定义颜色
    colors: {
      primary: '#26A79F'
    }
  },
  // 自定义快捷样式
  shortcuts: {
    'flex-col': 'flex flex-col',
    'flex-center': 'flex items-center justify-center',
    'flex-center-x': 'flex items-center',
    'flex-center-y': 'flex justify-center',
    'flex-center-between': 'flex-center-x justify-between',
    'flex-center-around': 'flex-center-x justify-around',
    'flex-col-center': 'flex-col items-center justify-center',
    'flex-col-between': 'flex-col justify-between',
    'flex-col-around': 'flex-col justify-around',
    'flex-col-center-x': 'flex-col justify-center',
    'flex-col-center-y': 'flex-col items-center'
  },
  // 自定义规则
  rules: [
    // 格式化成rpx
    [
      /^(m|mt|mb|ml|mr|mx|my|p|pt|pb|pl|pr|px|py|rd|lh)-(\d+)$/,
      ([, key, value]) => {
        const keys = {
          m: 'margin',
          mt: 'margin-top',
          mb: 'margin-bottom',
          ml: 'margin-left',
          mr: 'margin-right',
          mx: 'margin-left,margin-right',
          my: 'margin-top,margin-bottom',
          p: 'padding',
          pt: 'padding-top',
          pb: 'padding-bottom',
          pl: 'padding-left',
          pr: 'padding-right',
          px: 'padding-left,padding-right',
          py: 'padding-top,padding-bottom',
          rd: 'border-radius',
          lh: 'line-height'
        }
        return keys[key].split(',').reduce((acc, k) => ({ ...acc, [k]: `${value}rpx` }), {})
      }
    ],
    // bottom安全区域距离底部边界的距离
    [
      /^b-safe-(.*)$/,
      ([, value]) => ({
        bottom: `calc(${Number(value) ? `${value}rpx` : value} + env(safe-area-inset-bottom))`
      })
    ],
    // padding-bottom安全区域距离底部边界的距离
    [
      /^pb-safe-(.*)$/,
      ([, value]) => ({
        'padding-bottom': `calc(${Number(value) ? `${value}rpx` : value} + env(safe-area-inset-bottom))`
      })
    ],
    // 文字限制行数
    [
      /^text-row-(\d+)$/,
      ([, value]) => ({
        display: '-webkit-box',
        overflow: 'hidden',
        'text-overflow': 'ellipsis',
        '-webkit-box-orient': 'vertical',
        '-webkit-line-clamp': value
      })
    ]
  ]
})

安装插件

重启vscode后看到虚线效果(鼠标放上去看编译后的样式)

6. 精简项目(可选)

uni-app一堆依赖,但是我只开发微信小程序而已,却需要完全安装,也不知道哪个需要哪个不需要,看又看不懂,学又学不会,难搞

先贴个刚从官网拉下来的package.json

js 复制代码
{
  "name": "uni-preset-vue",
  "version": "0.0.0",
  "scripts": {
    "dev:custom": "uni -p",
    "dev:h5": "uni",
    "dev:h5:ssr": "uni --ssr",
    "dev:mp-alipay": "uni -p mp-alipay",
    "dev:mp-baidu": "uni -p mp-baidu",
    "dev:mp-jd": "uni -p mp-jd",
    "dev:mp-kuaishou": "uni -p mp-kuaishou",
    "dev:mp-lark": "uni -p mp-lark",
    "dev:mp-qq": "uni -p mp-qq",
    "dev:mp-toutiao": "uni -p mp-toutiao",
    "dev:mp-weixin": "uni -p mp-weixin",
    "dev:mp-xhs": "uni -p mp-xhs",
    "dev:quickapp-webview": "uni -p quickapp-webview",
    "dev:quickapp-webview-huawei": "uni -p quickapp-webview-huawei",
    "dev:quickapp-webview-union": "uni -p quickapp-webview-union",
    "build:custom": "uni build -p",
    "build:h5": "uni build",
    "build:h5:ssr": "uni build --ssr",
    "build:mp-alipay": "uni build -p mp-alipay",
    "build:mp-baidu": "uni build -p mp-baidu",
    "build:mp-jd": "uni build -p mp-jd",
    "build:mp-kuaishou": "uni build -p mp-kuaishou",
    "build:mp-lark": "uni build -p mp-lark",
    "build:mp-qq": "uni build -p mp-qq",
    "build:mp-toutiao": "uni build -p mp-toutiao",
    "build:mp-weixin": "uni build -p mp-weixin",
    "build:mp-xhs": "uni build -p mp-xhs",
    "build:quickapp-webview": "uni build -p quickapp-webview",
    "build:quickapp-webview-huawei": "uni build -p quickapp-webview-huawei",
    "build:quickapp-webview-union": "uni build -p quickapp-webview-union",
    "type-check": "vue-tsc --noEmit"
  },
  "dependencies": {
    "@dcloudio/uni-app": "3.0.0-4030620241128001",              // 核心包(不能删)
    "@dcloudio/uni-app-harmony": "3.0.0-4030620241128001",      // 鸿蒙
    "@dcloudio/uni-app-plus": "3.0.0-4030620241128001",         // APP
    "@dcloudio/uni-components": "3.0.0-4030620241128001",       // uni组件(不能删)
    "@dcloudio/uni-h5": "3.0.0-4030620241128001",               // h5
    "@dcloudio/uni-mp-alipay": "3.0.0-4030620241128001",        // 支付宝
    "@dcloudio/uni-mp-baidu": "3.0.0-4030620241128001",         // 百度
    "@dcloudio/uni-mp-jd": "3.0.0-4030620241128001",            // 京东
    "@dcloudio/uni-mp-kuaishou": "3.0.0-4030620241128001",      // 快手
    "@dcloudio/uni-mp-lark": "3.0.0-4030620241128001",          // 飞书
    "@dcloudio/uni-mp-qq": "3.0.0-4030620241128001",            // QQ
    "@dcloudio/uni-mp-toutiao": "3.0.0-4030620241128001",       // 头条
    "@dcloudio/uni-mp-weixin": "3.0.0-4030620241128001",        // 微信
    "@dcloudio/uni-mp-xhs": "3.0.0-4030620241128001",           // 小红书
    "@dcloudio/uni-quickapp-webview": "3.0.0-4030620241128001", // 快应用
    "vue": "^3.4.21",
    "vue-i18n": "^9.1.9"                                        // 多语言
  },
  "devDependencies": {
    "@dcloudio/types": "^3.4.8",                                // uni-app类型定义
    "@dcloudio/uni-automator": "3.0.0-4030620241128001",        // 自动化测试
    "@dcloudio/uni-cli-shared": "3.0.0-4030620241128001",       // 跨平台编译
    "@dcloudio/uni-stacktracey": "3.0.0-4030620241128001",      // 错误调试工具
    "@dcloudio/vite-plugin-uni": "3.0.0-4030620241128001",      // uni-app编译插件
    "@vue/tsconfig": "^0.1.3",                    
    "@vue/runtime-core": "^3.4.21",
    "typescript": "^4.9.4",
    "vite": "5.2.8",
    "vue-tsc": "^1.0.24"                                        // typescript类型检查
  }
}

如果只开发微信小程序,下面是精简后的package.json

js 复制代码
{
  "name": "uni-preset-vue",
  "version": "0.0.0",
  "scripts": {
    "dev": "uni -p mp-weixin",
    "build": "uni build -p mp-weixin"
  },
  "dependencies": {
    "@dcloudio/uni-app": "3.0.0-4030620241128001",
    "@dcloudio/uni-components": "3.0.0-4030620241128001",
    "@dcloudio/uni-mp-weixin": "3.0.0-4030620241128001",
    "vue": "^3.4.21"
  },
  "devDependencies": {
    "@dcloudio/types": "^3.4.8",
    "@dcloudio/uni-automator": "3.0.0-4030620241128001",
    "@dcloudio/uni-cli-shared": "3.0.0-4030620241128001",
    "@dcloudio/uni-stacktracey": "3.0.0-4030620241128001",
    "@dcloudio/vite-plugin-uni": "3.0.0-4030620241128001",
    "@vue/tsconfig": "^0.1.3",                    
    "@vue/runtime-core": "^3.4.21",
    "typescript": "^4.9.4",
    "vite": "5.2.8"
  }
}
相关推荐
CodeCraft Studio4 分钟前
Excel处理控件Spire.XLS系列教程:C# 合并、或取消合并 Excel 单元格
前端·c#·excel
头顶秃成一缕光15 分钟前
若依——基于AI+若依框架的实战项目(实战篇(下))
java·前端·vue.js·elementui·aigc
冴羽yayujs18 分钟前
SvelteKit 最新中文文档教程(17)—— 仅服务端模块和快照
前端·javascript·vue.js·前端框架·react
木木黄木木30 分钟前
HTML5图片裁剪工具实现详解
前端·html·html5
念九_ysl33 分钟前
基数排序算法解析与TypeScript实现
前端·算法·typescript·排序算法
海石33 分钟前
vue2升级vue3踩坑——【依赖注入】可能成功了,但【依赖注入】成功了不太可能
前端·vue.js·响应式设计
uhakadotcom1 小时前
Vite 与传统 Bundler(如 Webpack)在 Node.js 应用的性能对比
前端·javascript·面试
uhakadotcom1 小时前
Socket.IO 简明教程:实时通信的基础知识
前端·javascript·面试
机器视觉知识推荐、就业指导1 小时前
QML 批量创建模块 【Repeater】 组件详解
前端·c++·qml