# vue-cli 高级模板 **Repository Path**: tasmilen/vue-cli-template ## Basic Information - **Project Name**: vue-cli 高级模板 - **Description**: 基于vue官方最新cli4.x定制、含前端团队开发规范文档、适用中大型项目、适用PC | H5; ES6 + vue + vue-router + vuex + axios(荐) + lodash(荐) + element-ui(荐) | vant(荐) + VSCodeIDE(荐); - **Primary Language**: JavaScript - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 118 - **Created**: 2020-04-14 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README - [项目运行指南](#项目运行指南) - [开发本地环境变量](#开发本地环境变量) - [开发相关插件/工具](#开发相关插件工具) - [开发规范](#开发规范) - [vue](#vue) - [【保持单向数据流】](#保持单向数据流) - [【慎用全局注册】](#慎用全局注册) - [【组件名称】](#组件名称) - [【组件中的 CSS】](#组件中的-css) - [【统一标签顺序】](#统一标签顺序) - [【其它注意事项】](#其它注意事项) - [【 !!!其它则严格遵守 vue 官方风格指南】](#a-target_blank-hrefhttpscnvuejsorgv2style-guide其它则严格遵守-vue-官方风格指南a) - [vue-router](#vue-router) - [vuex](#vuex) - [模块复用](#模块复用) - [其它杂项](#其它杂项) - [代码注释](#代码注释) - [工程目录结构](#工程目录结构) - [前端部署](#前端部署) - [给 UI 的建议](#给-ui-的建议) - [填坑 Q 群:901842001](#填坑-q-群901842001) # 项目运行指南 - 安装/更新依赖包:`npm install` - 运行: - 启动为 dev 环境:`npm run serve` 或 `npm start` - 打包为 stage 环境:`npm run build:stage` - 打包为 prod 环境:`npm run build` - 检查并修复源码:`npm run lint` - 运行单元测试:`npm run test:unit` # 开发本地环境变量 - 新建 .env.development.local 来重写部分环境变量,如: - 模拟数据:`VUE_APP_MOCK = true` - 接口前缀:`VUE_APP_BASEURL_API = /api` - 接口地址:`DEV_PROXY_TARGET_API = http://10.25.73.159:8081` - ... # 开发相关插件/工具 - VSCode 相关插件 - 必要插件 - `ESLint` - `Vetur` - `Prettier - Code formatter` - `path Autocomplete` - 推荐插件 - `vscode-element-helper` (element-ui 专用) - `Debugger for Chrome` - `GitLens -- Git supercharged` - Chrome 相关插件 - 必要插件 - `vue-devtools` - 推荐插件 - `json-formatter` - 其它工具 - 推荐:`Postman` # 开发规范 ## vue ### 【保持单向数据流】 - 单个组件的数据流 ``` props、data/$store、computed (由前面派生) ↓ template/render ↓ 用户交互事件、初始化的异步回调 ↓ data/$store ``` - 组件间的数据流 - 父向子传递用 props - 子向父传递用 vue 内置的自定义事件 - 父子双向传递用 v-model.sync - 跨越传递用 vuex(慎用 EventBus) - 紧密耦合的祖孙间传递也可以考虑用父组件作为中间运输层 - 紧密耦合的兄弟间传递也可以考虑用父组件作为中转运输层 ### 【慎用全局注册】 - 组件、混入 ... 应使用局部注册 局部注册可保持清晰的依赖关系,并且 IDE 智能感知更为友好 ### 【组件名称】 - 名称大小写 ```html ``` - 使用前缀 - 非业务通用组件使用 Base 前缀 - 扩展/包装第三方开源组件或内部公共库组件使用 Ex 前缀 - 单例组件使用 The 前缀 ### 【组件中的 CSS】 - 使用 CSS Modules,基于如下考虑: - 不让外部进行样式重写,避免耦合 (与组件通信的唯一方式是 props) - 放心使用简短且语义强的 class 名,无需担心命名空间,使可读性更好 - 使用方式 - 语法 ```less /* 默认为局部 */ .xxx { } /* 从局部转到全局 */ :global(.yyy) { } // or :global { } /* 从全局转到局部 */ :local(.zzz) { } // or :local { } ``` - 单个组件专属 ```html ``` - 多个组件共用 (\*.module.less) ```js import style from './style.module.less' ``` ### 【统一标签顺序】 - script --> template --> style,并使用空行分隔 ### 【其它注意事项】 - 慎用 this\.\$refs、this\.\$parent、this\.\$root、provide/inject - this\.\$refs 一般用在第三方开源组件或内部公共库组件或非常稳定的组件,以调用显式声明的方法 - 暴露给外部的方法要加 pub 前缀,如:this\.\$refs.pubFocus() - 尽量不要在 watch 中变更数据,易造成死循环。数据变更应该交给用户交互事件或初始化的异步回调 - 组件中的 data 及 vuex 中的 state 应该可序列化,即不要存 undefined、function 等 ### 【 !!!其它则严格遵守 vue 官方风格指南】 --- ## vue-router - url 定义准则:path 对应视图变化 (使用 kebab-case 命名法),query 对应数据变化,hash 对应滚动条位置 `如:/project-list?type=1&search=keyword#position` - 路由的 name 值 (命名路由) 使用 kebab-case 命名法 - 视图跳转尽量使用声明式 ```html 使用声明式 使用命令式 ``` - 当组件依赖 \$route 时 (特别是 \$route.params),要使用路由组件传参,与 \$route 解耦 --- ## vuex - 需要由 vuex 管理的数据 - 组件间共享的响应式数据 - 组件间需要跨越传递的数据 - getter、mutation、action、module 使用驼峰命名法 - module 应避免嵌套,尽量扁平化 - module 应该启用命名空间 `namespaced: true` --- ## 模块复用 - 避免重复造轮子,多使用成熟的现成工具/类库/组件,如:lodash、qs、url-parse 等 - 模块设计原则: - 高内聚低耦合、可扩展 - 永远不要去改变模块输入的数据,如:函数参数、组件 prop - … - 方法接口的设计 ```js // 参数类型与个数要保持稳定 // 建议参数不要超过3个,且预留一个 options 对象,以提高扩展性 // 方法尽量纯净 (纯函数思想) export function myMethod1(a, options) {} // 当必选参数只有一个时 export function myMethod2(a, b, options) {} // 当必选参数只有两个时 export function myMethod3(options) {} // 当必选参数有两个以上时 export function myMethod4(options) {} // 当所有参数都是可选时 // 有时为了提高灵活性,参数类型可以是两重,一重是期望值,另一重是返回期望值的函数 (可带参) export function myMethod5(a) { a = typeof a === 'function' ? a() : a } ``` - 扩展/包装第三方开源组件或内部公共库组件 - 使用 extends 混入 (相关命名需要加 ex 前缀,防止覆盖) - 使用函数式组件包装 --- ## 其它杂项 - IDE 统一使用 VSCode,并统一使用相关插件及配置 - js 变量声明尽量使用 const - js 变量或对象属性使用驼峰命名法 - js 私有变量或对象私有属性使用 \_ 前缀 (注意: vue 组件属性不要使用 \_ 前缀) ```js // 表明该变量仅在 createId 方法中使用 (与 createId 方法紧挨着) let _count = 0 const createId = () => `${Date.now()}_${++_count}` // 适时使用立即执行函数可以简洁作用域及保护私有变量 const createId = (() => { let count = 0 return () => `${Date.now()}_${++count}` })() ``` - 导入模块时不要省略后缀(js 除外),利于 IDE 感知 - 当导入父层及以上目录中的模块时,建议使用'@'别名 ```js // js import XxxXxx from '@/components/XxxXxx.vue' ``` ```html ``` ```less /* style */ @import '~@/styles/vars.less'; .xxx { background: url('~@/assets/logo.png'); } ``` - **严格遵守 ESLint 语法校验**,警告级别的也要处理 (暂时用不到的代码可以先注释掉) - css - 全局 class 使用 g- 前缀 - CSS 选择器应避免深嵌套,尽量的扁平化 - 关键选择器 (最右边) 避免使用通配符 \* --- ## 代码注释 - 文档头部注释 - 脚本文件、样式文件 ```js /** * 说明 * @author 作者 */ ``` - vue 文件 ```html ``` - js 注释 (使用 JSDoc 注释标准,还能帮助 IDE 智能感知) - 注释格式 ```js /** * 大的区块、文档头部、JSDoc */ /* 一般的区块 */ // 小的区块、行 ``` - ES 2015 Modules ```js /** * 说明 * @author 作者 * @param {类型} a * @param {Object} options * @param {类型} options.x * @param {类型} options.y * @param {类型} [options.z] 可选参数 */ export function myMethod(a, options) {} /** * 类型参考:https://www.tslang.cn/docs/handbook/basic-types.html * * 基本 * @param {boolean} * @param {number} * @param {string} * @param {1|2|3} * @param {'a'|'b'|'c'} * * 数组 * @param {Array} * @param {Array} * * 函数 * @param {Function} * @param {(data)=>void} * @param {(data:Array)=>void|boolean} * * 对象 * @param {Object} * @param {any} * * 联合 * @param {number|string} * @param {boolean|(()=>boolean)} */ ``` - ES 2015 Classes - 待完成的功能 ```js /* TODO 说明 */ ``` - css 注释 - 全局样式一定要写注释 ```less /* 说明 */ .g-class1 { } /* 说明 */ .g-class2 { } ``` - vue template - 适当使用注释与空行 ```html
block1
block2
``` --- ## 工程目录结构 ``` |-- .env.development ------------ dev 环境变量 |-- .env.development.local ------ dev 本地环境变量 (被 git 忽略,需手动新建,用来重写部分环境变量) |-- .env.production-stage ------- stage 环境变量 |-- .env.production ------------- prod 环境变量 |-- .env.test |-- static-server.js ------------ 静态资源服务 (node 运行),通常用于预览/检查打包结果 |-- README.html ----------------- 由 README.md 手动生成 (使用 VSCode 插件 Markdown Preview Enhanced) |-- .vscode --------------------- 统一 VSCode 配置 |-- public | |-- favicon.ico | |-- index.html | |-- libs -------------------- 不支持模块化加载的 ES5 类库 (只能通过全局变量引用) |-- src |-- main.js |-- App.vue |-- libs -------------------- 支持模块化加载但是无法通过 npm 安装的 ES5 类库 |-- assets |-- styles | |-- global.less | |-- reset.less | |-- vars.less ----------- less 全局变量 | |-- xxx.less |-- scripts | |-- utils --------------- 通用方法 | |-- constants ----------- 常量 (多使用 Object.freeze) | |-- xxx.js | |-- http ---------------- axios 实例 | |-- index.js | |-- http.js | |-- createAxios.js | |-- xxx.js |-- injects ----------------- vue 全局注册 (慎用) | |-- index.js | |-- $xxx.js | |-- v-xxx.js | |-- mixin_xxx.js | |-- xxx.js |-- element-ui | |-- index.js | |-- rewrite ------------- 主题样式复写 | |-- index.less | |-- xxx.less |-- vant | |-- index.js | |-- vars.less ----------- 内置变量复写 | |-- rewrite ------------- 主题样式复写 | |-- index.less | |-- xxx.less |-- router | |-- index.js | |-- routes.js | |-- registerInterceptor.js |-- store | |-- index.js | |-- root.js | |-- xxx.js |-- api | |-- xxx.js | |-- mock ---------------- 模拟数据 | |-- index.js | |-- createMock.js | |-- xxx.js |-- components | |-- BaseXxx.vue --------- 非业务通用组件 | |-- TheXxx.vue ---------- 单例组件 | |-- ExXxx.vue ----------- 扩展/包装第三方开源组件或内部公共库组件 | |-- XxxXxx.vue | |-- ComponentExamples --- 非单例公共组件需要在这里写示例 | | |-- index.vue | | |-- XxxXxx.vue | |-- SvgIcon ------------- svg-sprite 图标组件 | | |-- index.vue | | |-- icons | |-- directives ---------- 可复用的自定义指令(局部注册) | | |-- xxx.js | |-- mixins -------------- 可复用的混入(局部注册) | |-- xxx.js |-- views |-- Xxx.vue |-- Xxx ----------------- 除了 api 和 vuex,其它的专属模块要内聚在同一目录下 |-- index.vue |-- Xxx.vue --------- 子路由组件 |-- xxx.js |-- xxx.module.less |-- components ------ 存放私有组件 ``` --- ## 前端部署 - 跨域处理 - 使用代理或 CORS - history 模式路由处理 - 如果 url 匹配的不是静态资源 (不带后缀的),则返回 /index.html 页面 - 客户端缓存处理 (配置响应头) - 静态资源 - 不缓存 `/index.html` ``` Cache-Control: no-store ``` - 强缓存 `/static-hash/**/*` ``` Cache-Control: public,max-age=31536000 ``` - 协商缓存 (默认) ``` Cache-Control: no-cache Etag: xxx Last-Modified: xxx ``` - XHR (解决 IE 缓存问题) ``` Cache-Control: no-cache ``` - gzip 压缩 - 静态资源:启用 gzip 压缩 (除了像素型图片) - XHR:发给客户端的响应数据超过指定阀值时应启用 gzip 压缩 --- ## 给 UI 的建议 - 对于中后台项目,在画 UI 界面时,建议参考前端已选型的开源组件库,并推荐使用开源组件库提供的制图元件/模板,如:element-ui - 对于 H5 项目,如:vant ## 填坑 Q 群:901842001 - 点击链接加入群聊