# 函数定义
动词+名词组合,驼峰拼接,体现动作和作用对象
动词 | 含义 | 用法示例 |
---|---|---|
get | 获取某个值 | getList |
set | 设置某个值 | setData |
switch | 切换某个值 | switchTab |
# 变量定义
标志性变量须固定前缀
前缀 | 含义 | 类型 | 用法示例 |
---|---|---|---|
show | dom 节点显示隐藏 | Boolean | v-if/v-show="showDom" |
is | 表示"是不是"含义的 | Boolean | isCheck |
has | 表示"有没有"含义的 | Boolean | hasList |
able | 表示"能不能"含义的 | Boolean | ableSubmit // true 能,false 不能 :disabled="!ableSubmit" |
v-for
遍历的list
变量
单页面若只有一个列表,直接用 mainList
;若有多个列表,可自定义语义化的 list
变量名 | 含义 | 类型 |
---|---|---|
mainList | 主列表 | Array |
doctorList、deptList... | 语义化列表 | Array |
v-for
循环代参
// 一级循环
v-for="(item, index) in xxxList"
// 二级循环:j标识
v-for="(jitem, jindex) in item.xxx"
// 三级循环:k标识
v-for="(kitem, kindex) in jitem.xxx"
# js 值为假的情况
值 | 类型 | 含义/使用场景 |
---|---|---|
false | boolean | 非真即假的情况 |
null | null | 初始化一个将来可能被赋值为"对象"的变量 作为函数的返回值 |
undefined | undefined | 函数声明未赋值时的默认值 |
' ' | string | 空字符串 |
0 | number | 数值 0 |
NaN | number | 数值 NaN |
// not good
if (param !== null && param !== undefined && param !== "") {
}
// good
if (param) {
}
# 生命周期书写顺序
- mixin
- components
- props
- data
- filter
- computed
- watch
- beforeCreate
- created
- beforeMount
- mounted
- beforeUpdate
- updated
- activated
- deactivated
- beforeDestroy
- destroyed
- errorCaptured
- methods
# 加载中&无数据
- 无数据变量(nodata)
参数 | 值 | 含义 |
---|---|---|
nodata | nodata = null | 初始化 |
nodata | nodata === true | 无数据(true 可省略) |
nodata | nodata === false | 有数据(一般用不上) |
- 计算列表是否无数据方法
/**
* @description 计算列表是否无数据
* @param {Array} list 列表
* @return {Boolean}
*/
switchNodata (list) {
return !list || list.length === 0
}
- vuex/state.js 定义所需全局变量
const state = {
isLoading: false, // 是否显示加载中遮罩层
loadingText: "" // 加载中文字提示
};
- 在 request/index.js 请求封装,统一控制加载中遮罩层的显示隐藏
可以通过方法调起加载中遮罩层,一般用于移动端
全局变量控制加载中控件的显示隐藏,一般用于 PC 端(不需要每个页面定义变量)
import store from '@/store'
/**
* @param option {
isLoading: {Boolean} 是否显示加载中,默认false
loadingText: {String} 加载中文字提示,默认'加载中...'
...
}
* @return {Promise} 请求结果
*/
const post = (option) => {
if (option.isLoading) {
if(mobile) {
wx.showLoading({
title: option.loadingText || '加载中...'
})
} else {
store.commit(this.$types.SET_IS_LOADING, true)
store.commit(this.$types.SET_LOADING_TEXT, option.loadingText)
}
}
return new Promise((resolve, reject) => {
...
// 请求完成
success: (res) => {
if(mobile) {
if (hasLoading) {
wx.hideLoading()
}
} else {
store.commit(this.$types.SET_IS_LOADING, false)
}
}
}
}
- xxx.vue 具体实现
<template>
<!-- 移动端 -->
<empty v-if="nodata" title="无数据"></empty>
<ul>
<li v-for="(item, index) in mainList" :key="index"></li>
</ul>
<!-- PC端,element-ui自带无数据判断 -->
<el-table
v-loading="isLoading"
:data="tableData"
:empty-text="无数据"
></el-table>
</template>
<script>
data() {
return {
nodata: null
}
},
computed: {
isLoading() {
return this.$store.state.isLoading
}
},
methods: {
getList() {
this.$post({
isLoading: true,
...
}).then(res => {
this.list = res.data
this.nodata = this.$util.switchNodata(this.list)
})
}
}
</script>
# 更好的写法
# 变量声明
一个函数作用域中所有的变量声明尽量提到函数首部,用一个 var 声明,不允许出现两个连续的 var 声明。
// not good
var value = 10;
var result = value + 10;
var i;
var len;
// good
var value = 10,
result = value + 10,
i,
len;
# 数组、对象
使用字面值创建对象
对象属性名不需要加引号
对象以缩进的形式书写,不要写在一行
数组、对象最后不要有逗号
语句末尾不加分号
// not good
var item = new Object();
// good
var item = {};
// not good
var a = {
b: 1
};
// good
var a = { b: 1 };
// not good
var a = {
b: 1,
c: 2
};
// good
var a = {
b: 1,
c: 2
};
# if else 改造
多层 if else 嵌套会使得代码不易理解,使用一些技巧改造 if else 帮助你写出更优雅的逻辑控制。
- 条件是否有关联,看一个登陆验证的场景
// bad
sumbit(){
if(hasUserName){
if(hasPassword){
// other code
}
}else{
}
}
// good
sumbit(){
if(!hasUserName){
return console.log("请输入名称")
}
if(!hasPassword){
return console.log("请输入密码")
}
// other code
}
- 条件之间有关联时,if else 改写。来看一个登陆成功的场景,假设用户身份为 common,vip,svip
// bad
if (userLevel === 0) {
console.log("common");
} else if (userLevel === 1) {
console.log("vip");
} else {
console.log("svip");
}
// good
const userLevelArr = ["common", "vip", "svip"];
console.log(userLevelArr[userLevel]);
如果的判断条件不是数字怎么办呢?
// bad
if (userLevel === "common") {
console.log("common");
} else if (userLevel === "vip") {
console.log("vip");
} else {
console.log("svip");
}
// good
const userLevelObj = {
common: "common",
vip: "vip",
svip: "svip"
};
console.log(userLevelObj[userLevel]);
- if else 简写技巧
// 一般写法
if (userLevel === "common") {
console.log("common");
}
// 简写
userLevel === "common" && console.log("common");
userLevel !== "common" || console.log("common");
- 条件强关联使用责任链模式,例如: vip 且入网满两年的用户送流量
// bad
if (userLevel === "vip") {
if (useAge > 2) {
console.log("赠送流量");
} else {
console.log("入网不满两年");
}
} else {
if (useAge > 2) {
console.log("您不是vip");
} else {
console.log("您不是vip且入网不满两年");
}
}
// perfect
const rules = [
{
match : function(isVip,hasTowYear){
return isVip && hasTowYear
},
action : function(){
console.log("赠送流量")
}
},
{
match : function(isVip,hasTowYear){
return !isVip && hasTowYear
},
action : function(){
console.log("您不是Vip")
}
},
{
match : function(isVip,hasTowYear){
return isVip && !hasTowYear
},
action : function(){
console.log("入网不满两年")
}
},
{
match : function(isVip,hasTowYear){
return !isVip && !hasTowYear
},
action : function(){
console.log("您不是vip且入网不满两年")
}
}
]
// 责任链模式,当逻辑变动时只需修改对应的数组
handler(isVip,hasTowYear){
for(let i in rules){
rules[i].match(...arg) && rules[i].action(...arg)
}
}
# 规范细则
方法遵循单一职责原则,一个方法只做一件事情,不可把方法写的过于复杂
避免
this
指向问题,方法统一用es6
箭头函数,因为es6
箭头函数的内部没有this
,因此函数内的this
就是声明函数时所处上下文中的this
对上下文this
的引用统一使用self
来定义尽量用'===', '!=='代替'==', '!='
异步方法尽量用
Async/await
// async方法定义
async getPatientList() {
await this.$post({
url: xxx,
param: xxx
}).then(res => {
this.patientList = res.data.list
})
}
// 在普通方法调用
demo1 () {
this.getPatientList().then(() => {
this.checkedPatient = this.patientList[0]
})
}
// 在异步方法调用
async demo2() {
await this.getPatientList()
this.checkedPatient = this.patientList[0]
}
- 无序静态列表(如个人中心我的 xxx),用循环来写,差异在
data
中去处理
data() {
return {
myList: [
{
icon: 'theicon-myrecipe',
title: '我的处方',
tapEvent: () => {
this.$router.push('/pages/buy_medicine')
}
},
{
icon: 'theicon-feedback',
title: '帮助与反馈',
tapEvent: () => {
this.$router.push('/pages/personal/help_feedback_manage')
}
}
]
}
}
返回上一页统一用
$router.back()
方法,不用$router.go()
避免重复跳转的页面(如下单),用
$router.replace
重定向跳转下一页路由懒加载
// not good
{
path: '/index',
name: 'index',
component: resolve => require(['@/pages/index.vue'], resolve)
}
// good
{
path: '/index',
name: 'index',
component: () => import('@/pages/index.vue')
}
- 组件懒加载
// not good
components: {
dialogUserinfo: resolve => {
require(["@/components/dialogUserinfo.vue"], resolve);
};
}
// good
components: {
dialogUserinfo: () => import("@/components/dialogUserinfo");
}
使用
es6/es7
语法请用babel-polyfill
组件进行转译所有变量 / 函数先声明后使用
尽量避免使用
eval()
图片规范 →