Vue框架的组合API的主要用途是更加灵活地对项目进行模块化的分割。如果setup()函数本身非常庞大,也必须对它进行分割,这样才能发挥组合API的特长。
对setup()函数的分割包括以下两个步骤。
(1) 把setup()函数分割成多个函数,把处理相关业务逻辑的代码分割到同一个函数中。
(2)把从setup()函数中分割出来的每个函数放到单独的.js文件中。
1、把setup()函数分割到多个函数中
例程1定义了PersonFull组件,它的setup()函数会返回person和persons变量,这两个变量都支持响应式机制。setup()函数还会返回add()和remove()方法。add()方法向persons.array数组中加入一个person对象,remove()方法从persons.array数组中删除特定的person对象。
■ 例程1 PersonFull.vue
<template>
<div>
<p>姓名:<input type="text" v-model="person.name"></p>
<p>年龄:<input type="text" id="" v-model="person.age"></p>
<p><button @click="add()">添加</button></p>
</div>
<div>
<ul>
<li v-for="v in persons.array" :key="v.id" >
ID:{{v.id}},姓名:{{ v.name }},年龄:{{ v.age }}
<button @click="remove(v.id)" >删除 </button>
</li>
</ul>
</div>
</template>
<script>
import { reactive} from 'vue'
export default {
setup() {
const { persons, remove } = useRemovePerson()
const { person, add } = useAddPerson(persons)
return { persons,remove, person, add}
}
}
// 向persons数组添加新的person对象
const useAddPerson = (persons) => {
const person= reactive({ id: '', name: '', age: '' })
const add = (()=> {
//计算新添加person对象的id
let index=null
for( index in persons.array){
if(person.id<=persons.array[index].id)
person.id=persons.array[index].id+1
}
//创建person对象的复制,该复制不支持响应式机制
const personCopy = Object.assign({},person)
//添加person对象
persons.array.push(personCopy)
person.id = ''
person.name = ''
person.age = ''
})
return { person,add }
}
// 删除一个person对象
const useRemovePerson = () => {
//包含了所有的person对象
const persons = reactive({
array: [
{ id: 1, name: "Mary", age: 17 },
{ id: 2, name: "Tom", age: 20 },
{ id: 3, name: "Linda", age: 18 },
]
})
const remove = (id) => {
//根据id删除特定的person对象
persons.array =persons.array.filter((v) => v.id !== id)
}
return { persons, remove }
}
</script>
PersonFull组件的setup()函数分割出来两个函数:useAddPerson()和useRemovePerson()。useAddPerson()定义并且返回person变量和add()方法,useRemovePerson()定义并且返回persons变量和remove()方法。
在setup()函数中,利用JavaScript的解构语法,从useAddPerson()和useRemovePerson()函数的返回值中获得相关的变量和方法,然后再由setup()函数把它们返回:
setup() {
const { persons, remove } = useRemovePerson()
const { person, add } = useAddPerson(persons)
return { persons,remove, person, add}
}
Vue组件的混入块也是分割组件的一种方式,是把组件分割成多个混入块,这些混入块没有输入参数和输出值,就像没有生命力的代码,必须把它们合并到组件中才会工作。而setup()函数分割出来的模块仍然是函数,可以有输入参数和返回值,还可以与其他函数模块交换数据,因此这样的模块既能够独立完成特定的功能,又能够方便地与其他的模块整合。这种分割方式更有助于开发团队按照业务逻辑来划分任务并进行分工合作。
在index.js中为PersonFull.vue组件设置的路由如下:
{
path: '/full',
name: 'full',
component: PersonFull
}```
通过浏览器访问http://localhost:8080/#/full,会显示如图1所示的网页。
![640.png](https://ucc.alicdn.com/pic/developer-ecology/qd74tgabmnnce_212a7c89c9de4487a5bfe1cf671ba65e.png)
# 2、把setup()函数分割到多个文件中
上文虽然从setup()函数中分割出了useRemovePerson()和useAddPerson()函数,但是它们都位于同一个PersonFull.vue文件中。下面将把它们放到单独的文件中,进一步提高每个函数模块的独立性。
可以把例程1的PersonFull.vue拆分成三个文件:Person.vue、remove.js和add.js,参见例程2、例程3和例程4。
■ 例程2 Person.vue
…
setup() {
const { persons, remove } = useRemovePerson()
const { person, add } = useAddPerson(persons)
return { persons,remove, person, add}
}
}
■ 例程3 remove.js
import { reactive} from 'vue'
// 删除一个person对象
const useRemovePerson = () => {
…
return { persons, remove }
}
export default useRemovePerson
■ 例程4 add.js
import { reactive} from 'vue'
// 向persons数组添加新的person对象
const useAddPerson = () => {
…
return { person, add }
}
export default useAddPerson
在index.js中,为Person组件设置的路由如下:
{
path: '/person',
name: 'person',
component: Person
}
通过浏览器访问http://localhost:8080/#/person,会显示图1所示的网页。