最近刚好带团队内的新人快速上手vue2这个版本的语法,今天也继续来分享下带他们去由0到1使用vue-cli构建vue项目,并分享下我们团队内vue技术栈平时开发中需要注意的一些规范,大家来看看吧,一起加油!
Begin:
Download nodejs from http://npm.taobao.org/mirrors/node/
My nodejs-version => node -v =>12.19.1
npm-version => npm -v => 6.14.8
Change your npm:
The first way:
1.Check your npm registry
Command: npm config get registry
Get default registry is:
https://registry.npmjs.org/
2.We will change it to https://registry.npm.taobao.org/
Command => npm config set registry https://registry.npm.taobao.org
Get the npm registry is:
Command: npm config get registry
https://registry.npmjs.org/
The second way:
1.Install NRM to manage your NPM registry:
Command:npm i nrm -g => For global installation
2.Check your npm registry now
Command:nrm ls
You will get like this:
* npm -------- https://registry.npmjs.org/
yarn ------- https://registry.yarnpkg.com/
cnpm ------- http://r.cnpmjs.org/
taobao ----- https://registry.npm.taobao.org/
nj --------- https://registry.nodejitsu.com/
npmMirror -- https://skimdb.npmjs.com/registry/
edunpm ----- http://registry.enpmjs.org/
3.Change npm registry:
Command:nrm use xxx => like nrm use taobao
End
Access to official website => https://cli.vuejs.org/zh/guide/installation.html
Find the way to install vue-cli:
Now command is:
npm install -g @vue/cli => For global installation
Check it:
vue --version / vue -V
Update it:
npm update -g @vue/cli
1.Create project:
Command:vue create /*your project name => Must be lowercase*/
like this:vue create my-vuecli
2.Test run:
Command:npm run serve
3.Create project base directory:
root:
docs: Development documentation
README.html =>
README.md =>
public:
favicon.ico
index.html
libs => 不支持模块化加载的第三方 ES5 类库/模块 (只能通过全局变量引用)
src:
1.api => Used to manage network requests
2.assets => 静态资源库
3.components => 公共组件库
4.config => 全局配置
5.datas => 全局静态数据工具库(json/js) => 比如省市区的地址数据json、全局菜单配置
6.filters => vue全局过滤工具库
7.http => 数据请求以及封装层
8.icons => 图标库
9.layout => 项目主界面布局层
components => 主界面组件
index.vue => 主界面
10.libs => 第三方组件/插件库
11.mock => 模拟数据请求库
11.router => vue-router配置层
index.js => 路由
12.styles/sass => for CSS pretreatment
13.store => Vuex配置层
local => 国际化
modules => 模块库
index.js => 根vuex
14.utils => 工具库
15.validator => 校验数据工具库
16.view => 视图库(页面)
App.vue //根组件
main.js // vue实例入口
/*
上面的层级还可以加入一些全局配置方法目录比如:
injects: vue 全局注册 (慎用)
filters:全局过滤器
mixin:全局混入
等等
*/
.env.development => dev 环境变量
.env.development.local => dev 本地环境变量 (被 git 忽略,需手动新建,用来重写部分环境变量)
.env.production-stage => stage 环境变量
.env.production => prod 环境变量
安装/更新依赖包:
npm install
运行:
可以使用 --mode= 后面加模式启动
启动为 dev 环境:npm run serve
或 npm start
=> 也可以使用 --mode=development
打包为 stage 环境:npm run build:stage
打包为 prod 环境:npm run build
检查并修复源码:npm run lint
运行单元测试:npm run test:unit
启用静态资源服务:npm run dist
版本号操作:
npm version major|minor|patch
新建 .env.development.local 来重写部分环境变量,如:
VUE_APP_MOCK = true
DEV_PROXY_TARGET_API = http://10.25.73.159:8081
ESLint
Vetur
Prettier - Code formatter
path Autocomplete
stylelint
vscode-element-helper
(element-ui 专用)Debugger for Chrome
GitLens -- Git supercharged
vue-devtools
json-formatter
Postman
或 Postwoman
props、data/$store/$route、computed (由前面派生)
↓
template/render
↓
用户交互事件、初始化的异步回调
↓
data/$store/$route
父向子传递用 props
子向父传递用 vue 内置的自定义事件,即 this.$emit
父子双向传递用 v-model 或 .sync
跨越传递用 vuex(慎用 EventBus)
紧密耦合的祖孙间传递也可以考虑用父组件作为中间运输层
紧密耦合的兄弟间传递也可以考虑用父组件作为中转运输层
组件、混入 ... 应使用局部注册
局部注册可保持清晰的依赖关系,并且 IDE 智能感知更为友好
<template>
<div>
<!-- 在 template 中一律使用 kebab-case 方式调用 -->
<my-component />
<el-input />
</div>
</template>
<script>
import MyComponent from '@/components/MyComponent.vue' // 文件名使用 PascalCase 命名法
export default {
name: 'ComponentName', // 必须有 name
components: {
MyComponent },
}
</script>
使用css Modules,基本如下考虑:
使用方法
语法
/* 默认为局部 */
.xxx {
}
/* 从局部转到全局 */
:global(.yyy) {
}
// or
:global {
}
/* 从全局转到局部 */
:local(.zzz) {
}
// or
:local {
}
单个组件专属
<style lang="less" module>style>
多个组件共用 (*.module.scss)
import style from './style.module.less'
其余的可以参考官方推荐风格:https://cn.vuejs.org/v2/style-guide/ or https://www.kancloud.cn/cyyspring/vuejs
url 定义准则
path 对应视图变化,query 对应数据变化,hash 对应滚动条位置
path 使用 kebab-case 命名法,并且尽量与组件名相匹配(即一眼看到 path 就能迅速找到对应的组件)
路由 path:/project-list
↓
路由组件:@/views/ProjectList.vue | @/views/ProjectList/index.vue
命名路由的 name 值使用 kebab-case 命名法,并且嵌套时要带命名空间(使用简写)
export const routes = {
path: '/user-center',
name: 'user-center',
// ...
children: [
{
path: 'base-info',
name: 'uc-base-info', // 带命名空间 uc-
// ...
},
],
}
当组件依赖 $route 作为核心数据时,要使用路由组件传参,与 $route 解耦,也使得依赖更为显式清晰
export const routes = {
path: '/project-detail',
props: ({
query: {
id } }) => ({
id }),
// ...
}
视图跳转尽量使用声明式(特别是 PC 端)
<router-link :to="path | { name, ... }">使用声明式router-link>
<a @click="$router.push(...)">使用命令式a>
namespaced: true
避免重复造轮子,多使用成熟的现成工具/类库/组件,如:lodash、qs、url-parse、date-fns/format 等
模块设计原则:
hasToolbar?=false 或 noToolbar?=false
方法接口的设计
// 参数类型与个数要保持稳定
// 建议参数不要超过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
}
扩展/包装第三方开源组件或内部公共库组件 (不建议使用高阶组件)
js 变量声明尽量使用 const/let
js 变量或对象属性使用驼峰命名法
js 私有变量或对象私有属性使用 _ 前缀 (注意: vue 组件属性不要使用 _ 前缀)
// 表明该变量仅在 createId 方法中使用 (与 createId 方法紧挨着)
let _count = 0
const createId = () => `${
Date.now()}_${
++_count}`
// 适时使用立即执行函数可以简洁作用域及保护私有变量
const createId = (() => {
let count = 0
return () => `${
Date.now()}_${
++count}`
})()
导入模块时不要省略后缀(js 除外),利于 IDE 感知
导入当前目录以外的模块时,建议使用’@'别名
// js
import XxxXxx from '@/components/XxxXxx.vue'
<img src="@/assets/logo.png" />
/* style */
@import '~@/styles/vars.less';
.xxx {
background: url('~@/assets/logo.png');
}
严格遵守 ESLint 语法校验,警告级别的也要处理 (暂时用不到的代码可以先注释掉)
css
文件头部注释
脚本文件、样式文件
/**
* 说明
* @author 作者
*/
vue 文件
js 注释 (结合 JSDoc 注释标准,帮助 IDE 智能感知)
注释格式
/**
* 文件头部、大的区块、JSDoc
*/
/* 一般的区块 */
// 小的区块、行
ES 2015 Modules
/**
* 使用 param 表示函数形参
* 使用 returns 表示函数返回值
* @param {类型} data
* @param {object} [options] 可选参数
* @param {类型} options.xxx
* @param {类型 =} options.yyy 可选属性
* @returns {类型}
*/
export function myMethod(data, options) {
}
/**
* 使用 type 进行类型断言
* @type {import('vue-router').RouteConfig[]}
*/
const routes = []
/**
* 使用 typedef 定义类型,方便多处使用(命名时需要首字母大写)
* @typedef {routes[0]} RouteConfig
* @param {(meta: object, route: RouteConfig) => boolean} filterCallback
* @returns {RouteConfig[]}
*/
export const filterMapRoutes = function(filterCallback) {
}
/**
* 类型参考:https://www.tslang.cn/docs/handbook/basic-types.html
*
* 基本
* @type {boolean}
* @type {number}
* @type {string}
* @type {1 | 2 | 3}
* @type {'a' | 'b' | 'c'}
*
* 数组
* @type {Array}
* @type {string[]}
*
* 函数
* @type {Function}
* @type {(data) => void}
* @type {(data: Array) => void | boolean}
*
* 对象
* @type {object}
*
* 联合
* @type {number | string}
* @type {boolean | (() => boolean)}
*
* 导入 ts 类型
* @type {import('xxx').yyy}
*
* 从现有的 js 变量或 ts 类型进行推导
* @type {Parameters} 取函数形参的类型
* @type {Parameters[0]} 取函数第一个形参的类型
* @type {ReturnType} 取函数返回值的类型
* @type {obj['xxx']} 取指定属性值的类型(不能使用点语法)
* ...
*/
ES 2015 Classes
待完成或待优化的地方
/* TODO: 说明 */
css 注释
全局样式需要写注释
/* 说明 */
.g-class1 {
}
/* 说明 */
.g-class2 {
}
vue template 注释
适当使用注释与空行
<div>block1div>
<div>block2div>