【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"
  }
}
相关推荐
小高0071 天前
JavaScript 内存管理是如何工作的?
前端·javascript
是大林的林吖1 天前
解决 elementui el-cascader组件懒加载时存在选中状态丢失的问题?
前端·javascript·elementui
鹏仔工作室1 天前
elemetui中el-date-picker限制开始结束日期只能选择当月
前端·vue.js·elementui
一 乐1 天前
个人博客|博客app|基于Springboot+微信小程序的个人博客app系统设计与实现(源码+数据库+文档)
java·前端·数据库·spring boot·后端·小程序·论文
sTone873751 天前
Android Room部件协同使用
android·前端
晴殇i1 天前
前端代码规范体系建设与团队落地实践
前端·javascript·面试
用户74054639943091 天前
Vite 库模式输出 ESM 格式时的依赖处理方案
前端·vite
开发者小天1 天前
React中使用useParams
前端·javascript·react.js
lichong9511 天前
Android studio release 包打包配置 build.gradle
android·前端·ide·flutter·android studio·大前端·大前端++
nvvas1 天前
npm : 无法加载文件 D:\nvm\nodejs\npm.ps1,因为在此系统上禁止运行脚本问题解决
前端·npm·node.js