Vue.js 中被低估的一个特性,看完后该去重构代码了

Vue.js 有很多强大和方便的功能特性,比如数据绑定和监听、组件生命周期钩子、各种内置模板指令等。

但我今天要说的一个特性,同样非常重要,却被很多人忽略了,那就是计算属性。可以说它是 Vue 最重要的特性之一。

为什么这么说呢?主要理由有两个:

  1. 计算属性倾向于声明式的代码
  2. 声明式代码更好
    既然关键理由在于声明式代码,我们就来看看到底什么是声明式代码。

看完本文你就会理解:

  • 什么是声明式代码,以及它跟命令式代码的区别
  • 为什么你更喜欢声明式代码——尽管自己还没有意识到
  • 计算属性如何实现声明式代码
  • 到底为什么声明式代码如此重要 很多组件有过多的 props,计算属性就能解决这个问题。

什么是声明式代码?

计算机编程最普遍的做法是给出一系列指令。计算机会一步步执行这些指令,直到程序终止。

这就是命令式编程

这就好比你教别人烹饪,对于一个从来没进过厨房的人来说,就算你把食材配料全都给他,也不能指望他能做出什么美味佳肴来。相反,你需要告诉他具体的步骤,越详细越好:

  • 切菜

    • 用刀的方法
    • 切多厚
  • 炒菜

    • 放多少水
    • 加多少盐
    • 用多大火,炒多久

缺了其中任何一个环节,最后的菜肴可能是不同的味道,甚至完全不能吃了。

但如果你让有经验的厨师来做呢?你不需要告诉他每一步怎么做,你只要给他食材,吩咐他做什么菜,剩下的就全交给厨师了。

这就是声明式编程

不需要指定程序的每一个执行步骤,只要告诉计算机应该做什么,计算机就会处理剩下的事情。

这就是你喜欢的 Vue

你跟其他开发者之所以那么喜欢用 Vue,正是因为它遵循了这个方法。

你只要在模板里写一个 v-for,不用写任何循环逻辑步骤,为数组里的每一项对应添加 DOM元素。

也不用操心数组改变了需要做什么,不需要一个个遍历 DOM 元素然后更新以保持跟数据同步。

Vue 已经替我们安排得明明白白,只要告诉 Vue 我们想做啥就行了。

这个理念非常强大,它让开发变得简单和容易多了!

我们应该尽可能地利用这个理念,多写声明式代码,少写命令式代码。

而计算属性就是干这个的。

计算属性与声明式代码

假设有一个组件有一个list属性,它是一个数组,但渲染的时候只用到前三个元素:

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
26
27
28
29
30
31
32
33
34
export default {
props: {
list: {
type: Array,
},
},

data() {
return {
topThree: [],
};
},

watch: {
list: {
// 组件初始化立即调用
immediate: true,
handler() {
// 将前三个元素赋值给 `topThree` 变量
this.topThree = this.getTopThree(this.list);
},
},
},

methods: {
getTopThree(list) {
// 排序
list.sort();

// 返回前三个
return list.slice(2);
}
}
}

组件的状态数据topThree 总是包含列表的前三个元素,无论list怎么变。

步骤分解:

  1. 如果list改变,触发watch
  2. 传递this.listgetTopThree方法,获取列表前三项
  3. 更新组件状态

这里我们用的就是命令式方法,详细指定了每一步要做什么。

实际上,watch已经算是声明式的了,因为毕竟我们不需要再写任何检查props更新的逻辑代码。当list改变的时候,Vue 会自动执行指定的函数。

但如果我们用计算属性,声明式会变得更彻底。你会发现它更简单、更容易理解。

更好的声明式代码

如果用计算属性来写,可以完全摆脱watch,连data属性都不用了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
export default {
props: {
list: {
type: Array,
},
},

computed: {
topThree() {
// 使用数组拷贝,避免副作用
const copy = this.list.slice();

// 排序
copy.sort();

// 返回前三项
return copy.slice(2);
}
}
}

这里要用数组拷贝,因为数组是引用类型,排序会影响到原数组。

通过这个简单的例子,我们可以感受到这种方式的好处:

  • 代码更少 — 代码行数减少了一大半
  • 更简单 — 从需要关注组件内4个部分(propsdatawatchmethods)到只需关心两个地方(propscomputed
  • 聚焦目标 — 我们不需要浪费时间去写什么代码来触发更新,因为这跟我们需要实现的功能没有直接关系。这一点对阅读代码的其他人来说非常重要,它有助于理解代码逻辑。

总结

本文介绍了什么是声明式代码,以及 Vue 深受喜爱的原因之一就是支持声明式代码。

我们还看到了计算属性是将命令式代码转为声明式代码的主要手段,好处也是明显的。

在工作项目当中,我见过太多的命令式的watch代码,把逻辑搞得一团糟,如果改成声明式的计算属性,代码会清晰得多。

希望文本让你对计算属性有个更好的认识,别再低估它了。

Kayson Li wechat
欢迎扫码关注我的微信公众号,订阅更多文章
坚持原创技术分享,您的支持将鼓励我继续创作!