组合式 API 语法糖
选项式 API
在 Vue2
中,我们基本上都是使用选项式 API 来开发项目的。
<script>
export default {
data() {
return {
// 逻辑1:存储学生数据
name: 'xiaoming'
age: 18
// 逻辑2:存储班级信息
className: 'class1'
classPeople: 50
}
},
methods: {
// 逻辑1:设置学生名称
setName(name) {
this.name = name
},
// 逻辑1:设置学生年龄
setAge(age) {
this.age = age
},
// 逻辑2:设置班级名称
setClassName(className) {
this.className = className
},
// 逻辑2:设置班级人数
setClassPeople(classPeople) {
this.classPeople = classPeople
}
}
}
</script>
<script>
export default {
data() {
return {
// 逻辑1:存储学生数据
name: 'xiaoming'
age: 18
// 逻辑2:存储班级信息
className: 'class1'
classPeople: 50
}
},
methods: {
// 逻辑1:设置学生名称
setName(name) {
this.name = name
},
// 逻辑1:设置学生年龄
setAge(age) {
this.age = age
},
// 逻辑2:设置班级名称
setClassName(className) {
this.className = className
},
// 逻辑2:设置班级人数
setClassPeople(classPeople) {
this.classPeople = classPeople
}
}
}
</script>
在上方组件代码中包含两个逻辑部分,一个是与学生有关的,另一个是与班级有关的,当然在大型的组件中可能会包含更多的逻辑部分。
这样的代码在初期可能会没什么感觉,但是在代码量维护达到一定标准时,例如大于 1000 行代码。就会存在一些问题。
查找代码变得困难
因为在这种情况下,我们需要在一个非常长的代码块中去寻找我们想要的代码然后修改。
例如我要修改逻辑 1 部分的代码,我就要去选项 data
methods
computed
watch
onMounted
... 中去查找,这些选项中又包含了其他不相关的部分,这样就会导致我们花费大量的时间去寻找我们想要的代码。甚至还有可能找漏。
排序混乱
在实际开发中,我们无法确保团队成员会按照逻辑 1、逻辑 2 整齐的顺序去编写代码。这也会使的我们阅读代码非常困难。
组合式 API
所以在 Vue3
中,官方推出了组合式 API 来解决这些问题。以下代码为组合式 API 的语法糖,比较推荐这种写法,原生写法暂时不介绍。
<script lang="ts" setup>
import { ref } from 'ref'
/**
* 逻辑1:存储学生数据
*/
const name = ref('xiaoming')
const age = ref(18)
/**
* 逻辑1:设置学生名称
*/
const setName = (name) => {
name.value = name
}
/**
* 逻辑1:设置学生年龄
*/
const setAge = (age) => {
age.value = age
}
/**
* 逻辑2:存储班级信息
*/
const className = ref('class1')
const classPeople = ref(50)
/**
* 逻辑2:设置班级名称
*/
const setClassName = (className) => {
className.value = className
}
/**
* 逻辑2:设置班级人数
*/
const setClassPeople = (classPeople) => {
classPeople.value = classPeople
}
</script>
<script lang="ts" setup>
import { ref } from 'ref'
/**
* 逻辑1:存储学生数据
*/
const name = ref('xiaoming')
const age = ref(18)
/**
* 逻辑1:设置学生名称
*/
const setName = (name) => {
name.value = name
}
/**
* 逻辑1:设置学生年龄
*/
const setAge = (age) => {
age.value = age
}
/**
* 逻辑2:存储班级信息
*/
const className = ref('class1')
const classPeople = ref(50)
/**
* 逻辑2:设置班级名称
*/
const setClassName = (className) => {
className.value = className
}
/**
* 逻辑2:设置班级人数
*/
const setClassPeople = (classPeople) => {
classPeople.value = classPeople
}
</script>
从上方代码中可能感觉区别不是很大,只是把逻辑相同的部分放到了一起。但是实际上组合式 API 强调的是简洁高效的逻辑复用。也就是说组合式 API 的代码可以单独抽离出来,然后在其他组件中进行复用。这个是选项式 API 做不到的,因为它高强度依赖 this
上下文。
逻辑抽离
组合式 API 还可以将逻辑模块抽离到外部文件中,进行复用。
<script lang="ts" setup>
import { name, age, setName, setAge } from './student'
import { className, classPeople, setClassName, setClassPeople } from './class'
console.log(name.value) // xiaoming
console.log(age.value) // 18
console.log(className.value) // class1
console.log(classPeople.value) // 50
</script>
<script lang="ts" setup>
import { name, age, setName, setAge } from './student'
import { className, classPeople, setClassName, setClassPeople } from './class'
console.log(name.value) // xiaoming
console.log(age.value) // 18
console.log(className.value) // class1
console.log(classPeople.value) // 50
</script>
import { ref } from 'ref'
/**
* 逻辑1:存储学生数据
*/
export const name = ref('xiaoming')
export const age = ref(18)
/**
* 逻辑1:设置学生名称
*/
export const setName = (name) => {
name.value = name
}
/**
* 逻辑1:设置学生年龄
*/
export const setAge = (age) => {
age.value = age
}
import { ref } from 'ref'
/**
* 逻辑1:存储学生数据
*/
export const name = ref('xiaoming')
export const age = ref(18)
/**
* 逻辑1:设置学生名称
*/
export const setName = (name) => {
name.value = name
}
/**
* 逻辑1:设置学生年龄
*/
export const setAge = (age) => {
age.value = age
}
import { ref } from 'ref'
/**
* 逻辑2:存储班级信息
*/
export const className = ref('class1')
export const classPeople = ref(50)
/**
* 逻辑2:设置班级名称
*/
export const setClassName = (className) => {
className.value = className
}
/**
* 逻辑2:设置班级人数
*/
export const setClassPeople = (classPeople) => {
classPeople.value = classPeople
}
import { ref } from 'ref'
/**
* 逻辑2:存储班级信息
*/
export const className = ref('class1')
export const classPeople = ref(50)
/**
* 逻辑2:设置班级名称
*/
export const setClassName = (className) => {
className.value = className
}
/**
* 逻辑2:设置班级人数
*/
export const setClassPeople = (classPeople) => {
classPeople.value = classPeople
}
如何选择选项式 API 和组合式 API
如果将相同逻辑部分用同一种颜色表示,那平时开发的组件代码将会是下图的效果。
选项式 API 更像是一个框架,会限制你的代码结构,让项目代码更加规范,同时它也将你锁定在规定的代码组织模式中,没有摆脱的余地,这会导致在更大规模的项目中难以进行重构或提高代码质量。
组合式 API 则是解除了这种限制,可以更加灵活的组织代码,以及逻辑复用,更适合长期项目的维护。
警告
由于组合式 API 相对比较灵活,代码组织需要你自己去规范,所以在团队开发中,如果没有统一的代码规范,那么组合式 API 可能会适得其反,导致代码混乱,不利于维护。