你在寻找Vue3移动端项目框架嘛?请看这里
现在web开发变得更加美妙高效,在于开发工具设计得更好了,丰富性与易用性,都有所提高。丰富性带来了一个幸福的烦恼,就是针对实际应用场景,如何选择工具 ?
1. Vue Cli和Vite之间的选择
Vite的开发环境体验好,基于浏览器原生ES6 Modules提供的功能,不对ES高版本语法进行转译,省略掉耗时的打包流程, 可是考虑到:
1) 项目要用到真机调试功能,开发环境下调试代码时不能使用ES高版本的语法,用着不顺畅。
后面发现可用@vitejs/plugin-legacy解决此问题。
import legacy from \'@vitejs/plugin-legacy\';
2) 受制于历史项目包袱,感受到Vite的一些痛点:
- Vite最新版2.7.x版本自带的less-loader, 将背景色的rgba属性转换成四位16进制在有些手机上存在兼容性问题。
- 与某些第三方工具库(比如说Cache-Router)不兼容,编译会报错。
- Vite的缓存机制,有时候让人有些困惑,代码修改了,重启之后都不生效,要手动删除node_modules下的.vite文件夹才生效。
- 给命令行动态添加自定义参数不太方便。
- Vite不支持装饰器语法,而有的第三方库用到了装饰器语法
3) Vite脚手架默认不集成TypeScript,Vue-Router,Vuex功能,使用起来不太方便
4) Vue Cli作为久经考验的成熟构建工具,稳定坑少,使用者众多,在生态环境和插件数量方面更好。
所以最终选择vue-cli最为Vue项目的脚手架。若是新项目,个人还是比较推荐使用Vite,构建速度确实快。
安装最新版本vue脚手架
npm install -g @vue/cli@next
安装成功后通过查看版本命令,确认是否安装成功
vue -V@vue/cli 5.0.0-rc.1
2 创建vue3项目
vue create vue3-demo
Vue CLI v5.0.0-rc.1
? Please pick a preset:
Default ([Vue 2] babel, eslint)
Default (Vue 3) ([Vue 3] babel, eslint) // 不选择默认的vue3配置,是因为没有vue-router+typescript功能,需要自己引入
> Manually select features // 手动选择特性
Vue CLI v5.0.0-rc.1? Please pick a preset: Manually select features
? Check the features needed for your project: (Press <space> to select, <a> to toggle all, <i> to invert selection, and <enter> to proceed)
>(*) Choose Vue version
(*) Babel // 添加babel
(*) TypeScript // 添加类型约束功能
( ) Progressive Web App (PWA) Support
(*) Router // 添加路由功能
(*) Vuex // 添加状态管理功能
(*) CSS Pre-processors // 添加样式预编译功能
(*) Linter / Formatter // 添加代码质量校验提示和格式化功能
( ) Unit Testing
( ) E2E Testing
Vue CLI v5.0.0-rc.1? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, TS, Router, Vuex, CSS Pre-processors, Linter
? Choose a version of Vue.js that you want to start the project with
2.x
> 3.x // 选择vue3
Vue CLI v5.0.0-rc.1? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, TS, Router, Vuex, CSS Pre-processors, Linter
? Choose a version of Vue.js that you want to start the project with 3.x
? Use class-style component syntax? (y/N) N // 是否使用class组件语法, ,选N 项目中用Composition API
为了在Vue中使用TypeScript中,许多开发者选择了Class-Style Component 解决方案,时至今日,还有另外一个方案,Composition API 撰写的代码会完美享用类型推导,并且也不用做太多额外的类型标注。这也同样意味着你写出的 JavaScript 代码几乎就是 TypeScript 的代码。即使是非 TypeScript 开发者也会因此得到更好的 IDE 类型支持而获益。
常规风格
export default {data(){
return {
selectOptions: [\'A1\', \'A2\'],
results: [],
// ...
}
}
}
class 组件风格
import { Vue, Component } from \'vue-property-decorator\'@Component
export default class Game extends Vue {
// 定义data
private selectOptions = [\'A1\', \'A2\']
private results: string[] = []
...
}
? Use class-style component syntax? Yes? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? Yes // 是否使用babel工具自动为转换后的 TypeScript 代码注入 polyfiills,此处选择 Y
? Use history mode for router? (Requires proper server setup for index fallback in production) Yes // 使用history网址路径风格,hash路径有点丑陋
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): Less // sass在国内安装经常出错,所以选less
? Pick a linter / formatter config: Prettier // 校验配置选择 eslint+prettier组合,沿袭项目使用习惯
? Pick additional lint features: Lint on save // 保存代码时校验代码质量, 提交代码时才去校验代码质量有些滞后
? Where do you prefer placing config for Babel, ESLint, etc. In dedicated config files // 将Babel,ESlint等配置文件从package.json中独立出来,因为json文件不能写注释
? Save this as a preset for future projects? Y // 将此配置保存起来,用于将来的项目 ,下次用vue-cli生成项目时,可以看到之前保存的配置项
启动服务
cd vue3-demo && yarn serve
在VSCode中打开app.vue发现文件中有许多红色的告警波浪线,安装Volar扩展,,绝大多数语法报错消失。顺便说一下为什么要使用Volar扩展,Vetur对<script setup>里面定义的响应式变量支持度不够好。
<script setup>// ...
// 仅用于template,未在script中被使用,会报 count is declared but its value is never read.Vetur(6133)
const count = ref(1)
//...
</script>
3 配置vue文件保存时自动格式化
代码美化功能,是一个重要的影响开发体验的指标。书写潦草的代码,按下Ctrl+S保存之后,瞬间变成整洁有序, 这种视觉感受,让人神清气爽。
在项目下新建.vscode/settings.json,内容如下:
{// ...
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[vue]": {
"editor.defaultFormatter": "johnsoncodehk.volar"
},
"[json]": {
"editor.defaultFormatter": "vscode.json-language-features"
},
// ...
}
修改项目下的.prettierrc文件为.prettierrc.js, 内容如下:
module.exports = {// 1.一行代码的最大字符数,默认是80(printWidth: <int>)
printWidth: 120,
// 2.tab宽度为2空格(tabWidth: <int>)
tabWidth: 2,
// 3.是否使用tab来缩进,我们使用空格(useTabs: <bool>)
useTabs: false,
// 4.结尾是否添加分号
semi: true,
// 5.使用单引号(singleQuote: <bool>)
singleQuote: true,
// 6.object对象中key值是否加引号(quoteProps: "<as-needed|consistent|preserve>")as-needed只有在需求要的情况下加引号,consistent是有一个需要引号就统一加,preserve是保留用户输入的引号
quoteProps: \'as-needed\',
// 7.在jsx文件中的引号需要单独设置(jsxSingleQuote: <bool>)
jsxSingleQuote: false,
// 8.尾部逗号设置,es5是尾部逗号兼容es5,none就是没有尾部逗号,all是指所有可能的情况,需要node8和es2017以上的环境。(trailingComma: "<es5|none|all>")
trailingComma: \'all\',
// 9.object对象里面的key和value值和括号间的空格(bracketSpacing: <bool>)
bracketSpacing: true,// 10.箭头函数单个参数的情况是否省略括号,默认always是总是带括号(arrowParens: "<always|avoid>")
arrowParens: \'always\',
// 11.range是format执行的范围,可以选执行一个文件的一部分,默认的设置是整个文件(rangeStart: <int> rangeEnd: <int>)
rangeStart: 0,
rangeEnd: Infinity,
// 12. requirePragma: <bool>,格式化有特定开头编译指示的文件 比如下面两种
/**
* @prettier
*/
// or
/**
* @format
*/
requirePragma: false,
// 13.insertPragma: <bool> 自动插入pragma到已经完成的format的文件开头
insertPragma: false,
// 14. proseWrap: "<always|never|preserve>" 文章换行,默认情况下会对你的markdown文件换行 进行format会控制在printwidth以内
proseWrap: \'always\',
// 15. htmlWhitespaceSensitivity: "<css|strict|ignore>" html中的空格敏感性
// html文档片段 1<b>2</b>3 原本显示为123, 不设置忽略空格的话格式化后会变成 1<b> 2 </b>3 显示为1 2 3
htmlWhitespaceSensitivity: \'ignore\',
// 16. vue script和style标签中是否缩进,开启可能会破坏编辑器的代码折叠
vueIndentScriptAndStyle: false,
// 17. endOfLine: "<lf|crlf|cr|auto>" 行尾换行符,默认是lf,
endOfLine: \'lf\',
// 18. 控制被引号包裹的代码是否进行格式化, 默认是auto,
embeddedLanguageFormatting: \'off\'
}
4 配置移动端UI库
做移动端开发,虽然定制性比较强。绝大多数UI库组件都用不到,但像Toast,Modal,Picker,Form,PullRefresh等组件几乎是必用,所以需要引入移动端UI库。
vue3移动端UI库的选择:
antd-mobile-vue-next | 移入项目之后,编译报错 |
Vux | UI风格是绿色系,与现有项目使用的蓝色系风格UI不符, 所以没用 |
Vant | 是业界主流的移动端组件库之一,UI色系风格与历史项目相符,支持vue3,组件功能优于Vux,已Toast为例,Vant提供了网络加载的Toast, Vux未提供。Vant总共提供了69个(不含组合api)涵盖基础,表单,反馈,展示,导航,业务六大类组件。 |
yarn add vant@3
按需引入
按需加载需要借助babel-plugin-import
, 这样就可以只引入需要的组件,以减小项目体积
yarn add babel-plugin-import -D
对babel.config.js进行配置
module.exports = {presets: ["@vue/cli-plugin-babel/preset"],
plugins: [
[
"import",
{
libraryName: "vant",
libraryDirectory: "es",
style: true,
},
"vant",
],
],
};
main.js中引入vant的样式
import { createApp } from "vue";import App from "./App.vue";
import "vant/lib/index.css";
createApp(App).mount("#app");
在App.vue中引入组件
<template><div>
<Button type="primary">主要按钮</Button>
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld msg="Welcome to Your Vue.js App" />
</div>
</template>
<script>
import HelloWorld from "./components/HelloWorld.vue";
import { Button } from "vant";
export default {
name: "App",
components: {
HelloWorld,
Button,
},
};
</script>
5 配置开发环境请求代理
请求代理是解决本地开发请求跨域的最佳方式之一,对前后端代码都没有侵入性。 在vue.config.js中添加代理转发配置:
const { defineConfig } = require("@vue/cli-service");module.exports = defineConfig({
transpileDependencies: true,
devServer: {
port: 9000,
host: "localhost",
https: false,
open: "/",
proxy: {
"/api": {
target: "http://192.168.xx.xx:50000",
secure: false,
changeOrigin: true,
logLevel: "debug",
},
},
},
// ....
});
6 配置路径别名
项目统一使用路径别名,好处是在代码中不用写../../../
之类让人看着有些云里雾里的文件引用路径,此外用短路径替代长路径,书写也更方便。而且编辑器对于别名路径也有提示,可以跳转。
需要注意的是,如果使用了TypeScript,除了要在vue.config.js中配置路径别名之外,还需要在tsconfig.json配置路径别名,否则虽然打包编译不报错,但是代码编辑器却会提示引用路径有错误。
vue.config.js路径别名配置
const path = require(\'path\');module.exports = {
configureWebpack: {
resolve: {
alias: {
\'@\': path.join(__dirname, \'src/\')
}
}
}
}
tsconfig.json路径别名配置
{"compilerOptions": {
// ...
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
}
},
"include": [
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
// 包含自定义声明文件
"typings/**/*.d.ts",
],
// ...
}
7 设置自定义环境变量
开发调试的时候,需要动态在命令行添加动态参数,用以执行开发环境的调试逻辑,将自定义的命令行参数传到业务文件的方法是:
在package.json中传入自定义环境变量
{// ...
"scripts": {
"start:wx": "ytt && vue-cli-service serve --mode local --wx true",
// ...
},
}
在vue.config.js中设置自定义环境变量
// ...const webpack = require(\'webpack\');
const { defineConfig } = require(\'@vue/cli-service\');
const { wx, mode } = require(\'minimist\')(process.argv.slice(2));
console.log({ wx, mode });
// console.log(process.env.VITE_API_HOST);
module.exports = defineConfig({
// ...
configureWebpack: {
plugins: [
// 定义环境变量
new webpack.DefinePlugin({
\'process.env.WX_JS_SDK_ENABLED\': wx, // 是否真机调试SDK模式
\'process.env.CURRENT_ENV\': JSON.stringify(mode),
}),
],
},
});
在业务文件中接收自定义环境变量
import { createApp } from \'vue\';import \'vant/lib/index.css\';
import App from \'./App.vue\';
import router from \'./router\';
import store from \'./store\';
console.log(process.env.WX_JS_SDK_ENABLED, process.env.CURRENT_ENV);
createApp(App).use(store).use(router).mount(\'#app\');
8 配置stylelint校验规则
stylelint的好处:
- 可以发现样式书写问题,如无效的十六进制值;重复的选择器;未命名的动画名称;错误的线性渐变语法;后面的属性覆盖前面的属性;前面的选择器优先级更高,覆盖后面的属性;选择器下未设置任何属性等。
- 能使所有人写的样式风格都一致,按照业内知名公司 (GitHub、Google、Airbnb)的样式规范要求写样式。
- 保存时自动对样式书写进行优化(如采用样式的简写形式,删除无意义小数点前面的0,调整样式顺序等),修复可以修复的样式错误。
1.安装依赖
yarn add -D stylelint stylelint-config-recess-order stylelint-order stylelint-config-standard stylelint-less stylelint-webpack-plugin postcss-html
2. 创建.stylelintrc.js 样式校验规则
module.exports = {plugins: [\'stylelint-less\'],
extends: [\'stylelint-order\', \'stylelint-config-standard\', \'stylelint-config-recess-order\'],
rules: {
indentation: 2,
\'at-rule-no-unknown\': [true, { ignoreAtRules: [\'mixin\', \'extend\', \'content\', \'include\'] }],
\'no-empty-source\': null, // null是关闭规则的意思--less文件内容可以为空
\'no-descending-specificity\': null, //禁止特异性较低的选择器在特异性较高的选择器之后重写
\'font-family-no-missing-generic-family-keyword\': null, // 关闭必须设置通用字体的规则
\'property-no-unknown\': [
true,
{
ignoreProperties: [\'box-flex\'], // 忽略某些未知属性的检测
},
],
\'selector-pseudo-element-no-unknown\': [
true,
{
ignorePseudoElements: [\'ng-deep\'], // 忽略ng-deep这种合法的伪元素选择器报警
},
],
\'declaration-colon-newline-after\': null, //一个属性过长的话可以写成多行
\'media-feature-name-no-unknown\': null, // 关闭禁止未知的媒体功能名
// 下面的排序规则是stylelint-config-recess-order的css排序规则,
// 要对某个属性排序进行调整,这个属性之前的样式排序都要配置在自定义属性排序中
\'order/properties-order\': [
{
// Must be first.
properties: [\'all\'],
},
{
// Position.
properties: [\'position\', \'top\', \'right\', \'bottom\', \'left\', \'z-index\'],
},
{
// Display mode.
properties: [\'box-sizing\', \'display\'],
},
{
// Flexible boxes.
properties: [\'flex\', \'flex-basis\', \'flex-direction\', \'flex-flow\', \'flex-grow\', \'flex-shrink\', \'flex-wrap\'],
},
{
// Grid layout.
properties: [
\'grid\',
\'grid-area\',
\'grid-template\',
\'grid-template-areas\',
\'grid-template-rows\',
\'grid-template-columns\',
\'grid-row\',
\'grid-row-start\',
\'grid-row-end\',
\'grid-column\',
\'grid-column-start\',
\'grid-column-end\',
\'grid-auto-rows\',
\'grid-auto-columns\',
\'grid-auto-flow\',
\'grid-gap\',
\'grid-row-gap\',
\'grid-column-gap\',
],
},
{
// Align.
properties: [\'align-content\', \'align-items\', \'align-self\'],
},
{
// Justify.
properties: [\'justify-content\', \'justify-items\', \'justify-self\'],
},
{
// Order.
properties: [\'order\'],
},
{
// Box model.
properties: [
\'float\',
\'width\',
\'min-width\',
\'max-width\',
\'height\',
\'line-height\',
\'min-height\',
\'max-height\',
\'padding\',
\'padding-top\',
\'padding-right\',
\'padding-bottom\',
\'padding-left\',
\'margin\',
\'margin-top\',
\'margin-right\',
\'margin-bottom\',
\'margin-left\',
\'overflow\',
\'overflow-x\',
\'overflow-y\',
\'-webkit-overflow-scrolling\',
\'-ms-overflow-x\',
\'-ms-overflow-y\',
\'-ms-overflow-style\',
\'clip\',
\'clear\',
],
},
{
// Typography.
properties: [
\'font\',
\'font-family\',
\'font-size\',
\'font-style\',
\'font-weight\',
\'font-variant\',
\'font-size-adjust\',
\'font-stretch\',
\'font-effect\',
\'font-emphasize\',
\'font-emphasize-position\',
\'font-emphasize-style\',
\'-webkit-font-smoothing\',
\'-moz-osx-font-smoothing\',
\'font-smooth\',
\'hyphens\',
\'color\',
\'text-align\',
\'text-align-last\',
\'text-emphasis\',
\'text-emphasis-color\',
\'text-emphasis-style\',
\'text-emphasis-position\',
\'text-decoration\',
\'text-indent\',
\'text-justify\',
\'text-outline\',
\'-ms-text-overflow\',
\'text-overflow\',
\'text-overflow-ellipsis\',
\'text-overflow-mode\',
\'text-shadow\',
\'text-transform\',
\'text-wrap\',
\'-webkit-text-size-adjust\',
\'-ms-text-size-adjust\',
\'letter-spacing\',
\'word-break\',
\'word-spacing\',
\'word-wrap\', // Legacy name for `overflow-wrap`
\'overflow-wrap\',
\'tab-size\',
\'white-space\',
\'vertical-align\',
\'list-style\',
\'list-style-position\',
\'list-style-type\',
\'list-style-image\',
],
},
{
// Accessibility & Interactions.
properties: [
\'pointer-events\',
\'-ms-touch-action\',
\'touch-action\',
\'cursor\',
\'visibility\',
\'zoom\',
\'table-layout\',
\'empty-cells\',
\'caption-side\',
\'border-spacing\',
\'border-collapse\',
\'content\',
\'quotes\',
\'counter-reset\',
\'counter-increment\',
\'resize\',
\'user-select\',
\'nav-index\',
\'nav-up\',
\'nav-right\',
\'nav-down\',
\'nav-left\',
],
},
{
// Background & Borders.
properties: [
\'background\',
\'background-color\',
\'background-image\',
"-ms-filter:\\\'progid:DXImageTransform.Microsoft.gradient",
\'filter:progid:DXImageTransform.Microsoft.gradient\',
\'filter:progid:DXImageTransform.Microsoft.AlphaImageLoader\',
\'filter\',
\'background-repeat\',
\'background-attachment\',
\'background-position\',
\'background-position-x\',
\'background-position-y\',
\'background-clip\',
\'background-origin\',
\'background-size\',
\'background-blend-mode\',
\'isolation\',
\'border\',
\'border-color\',
\'border-style\',
\'border-width\',
\'border-top\',
\'border-top-color\',
\'border-top-style\',
\'border-top-width\',
\'border-right\',
\'border-right-color\',
\'border-right-style\',
\'border-right-width\',
\'border-bottom\',
\'border-bottom-color\',
\'border-bottom-style\',
\'border-bottom-width\',
\'border-left\',
\'border-left-color\',
\'border-left-style\',
\'border-left-width\',
\'border-radius\',
\'border-top-left-radius\',
\'border-top-right-radius\',
\'border-bottom-right-radius\',
\'border-bottom-left-radius\',
\'border-image\',
\'border-image-source\',
\'border-image-slice\',
\'border-image-width\',
\'border-image-outset\',
\'border-image-repeat\',
\'outline\',
\'outline-width\',
\'outline-style\',
\'outline-color\',
\'outline-offset\',
\'box-shadow\',
\'mix-blend-mode\',
\'filter:progid:DXImageTransform.Microsoft.Alpha(Opacity\',
"-ms-filter:\\\'progid:DXImageTransform.Microsoft.Alpha",
\'opacity\',
\'-ms-interpolation-mode\',
],
},
{
// SVG Presentation Attributes.
properties: [
\'alignment-baseline\',
\'baseline-shift\',
\'dominant-baseline\',
\'text-anchor\',
\'word-spacing\',
\'writing-mode\',
\'fill\',
\'fill-opacity\',
\'fill-rule\',
\'stroke\',
\'stroke-dasharray\',
\'stroke-dashoffset\',
\'stroke-linecap\',
\'stroke-linejoin\',
\'stroke-miterlimit\',
\'stroke-opacity\',
\'stroke-width\',
\'color-interpolation\',
\'color-interpolation-filters\',
\'color-profile\',
\'color-rendering\',
\'flood-color\',
\'flood-opacity\',
\'image-rendering\',
\'lighting-color\',
\'marker-start\',
\'marker-mid\',
\'marker-end\',
\'mask\',
\'shape-rendering\',
\'stop-color\',
\'stop-opacity\',
],
},
{
// Transitions & Animation.
properties: [
\'transition\',
\'transition-delay\',
\'transition-timing-function\',
\'transition-duration\',
\'transition-property\',
\'transform\',
\'transform-origin\',
\'animation\',
\'animation-name\',
\'animation-duration\',
\'animation-play-state\',
\'animation-timing-function\',
\'animation-delay\',
\'animation-iteration-count\',
\'animation-direction\',
],
},
],
},
};
编译时自动修复
// ...const { defineConfig } = require(\'@vue/cli-service\');
const StylelintPlugin = require(\'stylelint-webpack-plugin\');
module.exports = defineConfig({
// ...
configureWebpack: {
plugins: [
// ...
new StylelintPlugin({
files: [\'src/**/*.vue\'],
// 编译时自动修复
fix: true,
// 这样配才能修复vue文件style片段中的less语法
customSyntax: \'postcss-html\',
}),
],
},
});
安装VSCode stylelint扩展
在.vscode/settings.json中配置保存代码时自动修复样式错误
{"editor.codeActionsOnSave": {
// ...
"source.fixAll.stylelint": true
},
// 关闭vscode自带的css,less,scss报错提示
"css.validate": false,
"less.validate": false,
"scss.validate": false,
"stylelint.validate": ["css", "less"]
}
9 配置yapi-to-typescript
typescript面世以来,经历了一个从厌烦到喜欢的过程,厌恶的是要在原来开发的基础上,多做一些繁杂数据类型定义的工作,喜欢的是确实帮助开发者发现了许多语法错误,享受到接口和传参的便利提示, 综合起来,还是利大于弊,所以 越来越多的开发者开始加入ts大家庭。yapi-to-typescript这个工具,可以帮我们省去接口数据类型定义的工作量。让我们更愉快的与ts玩耍。
安装依赖
yarn add -D yapi-to-typescript
创建ytt.config.ts配置文件
import { defineConfig } from \'yapi-to-typescript\';/**
* 生成Api接口名称 Interface和ChangeCase数据类型参见node_modules\yapi-to-typescript\lib\esm\index.d.ts定义
* @param interfaceInfo : Interface
* @param changeCase:ChangeCase
* @returns 请求响应接口名称--pascal命名
*/
function genApiInterfaceName(interfaceInfo, changeCase) {
// 取解析路径dir最尾部的路径作为前缀路径
const lastPath = interfaceInfo.parsedPath.dir.split(\'/\').pop();
// 拼接前缀路径+文件名称
return `${changeCase.pascalCase(lastPath)}${changeCase.pascalCase(interfaceInfo.parsedPath.name)}`;
}
export default defineConfig([
{
serverUrl: \'https://yapi.xxx.com\',
typesOnly: true,
target: \'typescript\',
reactHooks: {
enabled: false,
},
prodEnvName: \'项目名称\',
// 将生成文件路径转化成小驼峰命名方式
outputFilePath: (interfaceInfo, changeCase) => {
// 文件夹名称取api-url路径末尾2个
const filePathArr = interfaceInfo.path.split(\'/\').slice(-2);
const filePath = filePathArr.map((item) => changeCase.camelCase(item)).join(\'/\');
return `typings/httpTypes/${filePath}.ts`;
},
// 生成ts文件中请求参数interface名称,将下划线命名转换成pascal命名
getRequestDataTypeName: (interfaceInfo, changeCase) => {
return `${genApiInterfaceName(interfaceInfo, changeCase)}Request`;
},
// 生成ts文件中请求响应数据interface名称,将下划线命名转换成pascal命名
getResponseDataTypeName: (interfaceInfo, changeCase) => {
return `${genApiInterfaceName(interfaceInfo, changeCase)}Response`;
},
// 响应数据中要生成ts数据类型的键名
dataKey: \'retdata\',
projects: [
{
// token获取方式: 在yapi-设置-token配置中查看
token: \'xxx\',
// 分类id查找方式: 点击接口左侧的分类菜单,查看url地址栏最后面的数字获取
// 分类id配置特别重要,配置错了无法生成对应的ts数据类型定义文件
categories: [
{
id: [xxx], // 民生立减金API分类id
},
],
},
],
},
]);
3.在package.json中配置ytt指令
{// ...
"scripts": {
"start": "ytt && vue-cli-service serve --mode local",
"build": "ytt && vue-cli-service build --mode local",
"ytt": "ytt",
},
}
4.在.gitignore中添加对httpTypes下文件的忽略
# .../typings/httpTypes/*
# ...
10 配置commitlint
commit message 是程序员开发的日常高频操作,自然状态下commit message 呈现五花八门的书写风格,不利于阅读和维护,规范的 commit message 有助于团队做 code review, 输出清晰明了的 CHANGELOG, 有利于项目的长期维护。
安装依赖包
yarn add -D husky conventional-changelog-cli @commitlint/{cli,config-conventional}
创建提交校验配置文件commitlint.config.js
/*** git commit最佳实践
* 1.经常commit,One Thing,One Commit
* 2.commit之前测试,不要commit一半工作;
* 3.编写规范的commit message
*/
/**
* Commit message 包括三个部分:Header,Body 和 Footer
* <type>(<scope>): <subject>
* 空一行
* <body>
* 空一行
* <footer>
*/
module.exports = {
extends: [\'@commitlint/config-conventional\'],
rules: {
// Header包括三个字段:type(必需)、scope(可选)和subject(必需)。最多200字
\'header-max-length\': [2, \'always\', 200],
// 提交类型<type>枚举
\'type-enum\': [
2,
\'always\',
[
\'init\', // 项目初始化
\'clean\', // 清理过时无用文件
\'merge\', // 合并代码
\'style\', // 修改样式文件(包括css/less/sass,图片,字体文件)
\'format\', // 格式化,不影响代码含义的修改,比如空格、格式缩进、缺失的分号等
\'build\', // 改变构建流程、或者增加依赖库、工具等 如webpack.config.js,package.json yarn.lock
\'chore\', // 各种配置文件的修改, 如.gitignore,tsconfig.json,.vscode,.tenone, eslint/stylelint,envConfig
\'ci\', // 对CI配置文件或脚本进行了修改
\'docs\', // 修改项目说明文档
\'feat\', // 新增功能
\'fix\', // 修复bug
\'perf\', // 性能优化
\'refactor\', // 既不是修复bug也不是添加功能的代码重构
\'revert\', // 版本回退
\'test\', // 修改测试用例
],
],
// 格式-可选值
// \'lower-case\' 小写 lowercase
// \'upper-case\' 大写 UPPERCASE
// \'camel-case\' 小驼峰 camelCase
// \'kebab-case\' 短横线 kebab-case
// \'pascal-case\' 大驼峰 PascalCase
// \'sentence-case\' 首字母大写 Sentence case
// \'snake-case\' 下划线 snake_case
// \'start-case\' 所有首字母大写 start-case
// <type> 不能为空
\'type-empty\': [2, \'never\'],
// <type> 格式 小写
\'type-case\': [2, \'always\', \'lower-case\'],
// <scope> 关闭改动范围不能为空规则
\'scope-empty\': [0, \'never\'],
// <scope> 格式 小写
\'scope-case\': [2, \'always\', \'lower-case\'],
// <subject> 不能为空
\'subject-empty\': [2, \'never\'],
// <subject> 关闭 以.为结束标志
\'subject-full-stop\': [0, \'never\', \'.\'],
// <subject> 格式
\'subject-case\': [2, \'never\', []],
// <body> 以空行开头
\'body-leading-blank\': [1, \'always\'],
// <footer> 以空行开头
\'footer-leading-blank\': [1, \'always\'],
},
};
3. 创建提交校验shell脚本 husky.sh和commit-msg
yarn husky install
在.husky文件夹下创建commit-msg文件
npx husky add .husky/commit-msg
在.husky/commit-msg文件中写入
#!/bin/sh. "$(dirname "$0")/_/husky.sh"
# 提交记录检查
yarn commitlint --edit $1
# 代码重复率检测
yarn jscpd
# 格式化检查
yarn format:check
# eslint检查
yarn lint:check
11 配置代码重复率检测工具jscpd
代码的简洁之道有一条铁律是 Don\'t Repeat Yourself,那么如何快速地检测出项目出是否存在着大段的重复代码,靠人工检查显然不可取,这种重复体力活应该交给工具。
检测前端代码重复率的工具有jsinspect、jscpd,PMD-CPD(PMD\'s Copy/Paste Detector)
- jsinspect工具支持js和jsx格式的文件,基于抽象语法树,可以检测出结构类似的代码块
- PMD-CPD工具支持js文件检测,也可以自己开发扩展包来解析指定的语言
- jscpd工具支持文件格式广泛,如js、jsx、vue、ts、less,java、oc等。其重复率判定依据为一定长度标识符的MD5值是否相同
每个工具各有其优缺点,若只需要检测js或jsx文件,且对检测结果要求较高,可以选择jsinspect或者PMD-CPD工具,若考虑检测工具的通用性,可以选择jscpd工具。
安装:
npm install -g jscpd
用法:
jscpd src/*
在项目下创建.jscpd.json配置文件
{
// 重复率阈值"threshold": 0.1,
// 报告输出格式"reporters": [
"html",
"console"
],
"ignore": [
"dist/**",
"node_modules/**"
],
// 文件路径使用相对路径"absolute": false
}
--min-tokens | -k :代码的最小块大小。小于的代码块min-tokens将被跳过,默认为50; |
--min-lines | -l :最小代码行数,默认为5; |
--max-lines | -x : 最大代码行数,默认为1000; |
--max-size | -z :最大文件大小,单位为kb,默认100; |
--threshold | -t :重复级别的阈值,当项目重复级别大于该阈值时报错退出,默认为空; |
--ignore | -i :忽略的文件类型; |
--reporters | -r :输出类型 |
参考文献
Vue3+TS,写一个逼格满满的项目
Vue3,我决定不再使用Vuex
- vue.config.js配置项
prettier使用指南(包含所有配置项)
vue3 composition(组合式)API 是什么?我为什么要使用它?
检测前端代码重复率工具
Vue 3 生命周期完整指南
- Ant Design Pro Vue
- [try-catch优雅写法]
以上是 你在寻找Vue3移动端项目框架嘛?请看这里 的全部内容, 来源链接: utcz.com/z/376669.html