锐评 低血压代码

Author Avatar
Klein 4月 06, 2024

治疗高血压。那些年,让我蚌埠住,眼前一黑的代码。

先更新到这,以后想到其他再加上。别写了,再写就要犯高血压了

先叠甲:我的原则是对事不对人,写这篇文章不是为了鄙视别人,在别人身上找优越感。只是为了警醒自己并对自己之前工作的一些总结。

只会在弱者身上找乐子的人,这辈子也就是个弱者了,他始终缺了挑战强者的心。因为这种行为,本身就暗暗隐藏着对强者的畏惧。所以往往欺凌弱者的人,对强者也会卑躬屈膝。

refs 隔多代调用组件

这还是支付页的代码,你敢信?

1
2
// 大概就是这样,真事
this.$refs.father.$refs.children[0].$refs.grandsons.$refs.greatGrandson.method()

这样写代码耦合性很高,而且可维护性很差。因为它依赖于组件结构的具体层级。如果组件结构发生变化,那么这段代码就会失效,需要进行大量的修改。

你搁这套娃呢?

搁这套娃套上了。嵌套了十几层。不夸张,真事。

本来就不应该嵌套层级过深、选择器过于复杂。而且还有 Vue 的 scoped attribute 就更不应该这样写了。

反例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<style lang="less" scoped>
// 反例
.navbar {
background-color: #333;
color: #fff;

.nav-link {
text-decoration: none;
color: #fff;

.nav-link-a {
color: #fff;
// ...其实还有很多层嵌套,不一一列举了

}
}
}
</style>

编译出来:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.navbar[data-v-f3f3eg9] {
background-color: #333;
color: #fff;
}

.navbar[data-v-f3f3eg9] .nav-link {
text-decoration: none;
color: #fff;
}

.navbar[data-v-f3f3eg9] .nav-link .nav-link-a {
color: #fff;
}

...然后就是无穷无尽的嵌套

我的写法:

使用 & 引用父选择器优化 less 嵌套问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<style lang="less" scoped>
.button {
&-ok {
background-image: url("ok.png");
}
&-cancel {
background-image: url("cancel.png");
}

&-custom {
background-image: url("custom.png");

&:hover {
color: blue;
}
}
}
}
</style>

这样编译出来不会嵌套成一坨。

image.png

别惦记你那元素选择器了

其实这点是跟嵌套叠加在一起了。

经常看到这种既嵌套又滥用元素选择器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<style lang="less" scoped>
.navbar {
background-color: #333;
color: #fff;

p {
text-decoration: none;
color: #fff;

span {
color: #fff;
// ...其实还有很多层嵌套,不一一列举了

}
}
}
</style>

image.png

懂 CSS 选择器原理的不用再解释了吧。

您是不知道函数单一职责原则吗?

当我看到往 emaillogin 方法中加入手机登录的逻辑,还加上五六个 return。真的没绷住,您是不知道函数单一职责原则吗?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<script>
export default {
methods: {
emaillogin () {
// 这里是同事后来加的:
if (!this.isEmailRegister) {
if (!verifyPhone(this.phone, this.area_code)) {
this.phone_error = true
return false
}
if (this.phoneLoginShowPasswordInput && (!this.validatorData.password.text || this.validatorData.password.text.length < 6)) {
this.password_error = true
return
}
if (!this.phoneLoginShowPasswordInput && this.code.length !== 4) {
this.code_error = true
return
}
this.phoneLogin()
return
}
// 后面是我之前写的邮箱验证逻辑
}
}
</script>

求你了,用 ES6 吧

有很多地方可以用 ES6 写的,,懒得一一举例了。

  • include 代替 indexOf
  • 字符串模板
  • Promise 取代地狱回调
  • 解构赋值
    ……

map 不是这么用的

把 map 当成 forEach 用

1
2
3
4
5
6
7
8
9
10
11
12
13
// 反例
list.map(item => {
if (item.paths.indexOf('path') >= 0) {
item.i = false
}
})

// list
list.forEach(item => {
if (item.paths.includes('path')) {
item.i = false;
}
});

筛选特定元素为什么不直接用 filter 呢?

1
2
3
4
5
6
7
8
9
10
// 反例
const res = []
list.map(item => {
if (item.condition) {
res.push(item)
}
})

// 我会这样写
const res = list.filter(item => item.condition);

使用 padding 进行左右布局

父容器 用 padding-lefe 撑开右边的元素。

左边的子元素用 absolute 固定。

本来这么布局写法就不对,而且还失去了文档流的自适应性。适配多语言时还要一个一个适配。大开眼界,啥也不说了。

image.png

image.png

滥用 z-index

动不动就是 z-index: 999

求你了,写成计算属性吧。

无论多复杂多长的逻辑都要写在 template ,坚决不写计算属性。

template 写成一坨不仅可读性差,而且无法重复利用,可维护性也差。

算我求你了,写成计算属性吧。

computed 属性中做副作用操作

别在 computed 里做副作用操作,比如:发起请求或者设置 cookie.

getSaveParams 方法中调用订阅方法

我请假回来一看,眼前一黑。

这种感觉就像好好整理的房间里突然被拉了一坨答辩。

是的,你没有看错,在整理参数的方法 getSaveParams 中调用订阅请求。

全文注释等于没有注释

连个组件 props 的 email 都要注释 “邮箱”,太离谱了吧。

我的观点是:只要在代码中无法体现或特殊说明的地方才加注释

命名能不能认真点

我见过包括但不限于有随便命名的,缩写命名(pageSize 写成 ps)的, 反义命名的….