组合式API
# 组合式API
# 1.【OptionsAPI 与 CompositionAPI】
Vue2
的API
设计是Options
(配置)风格的。Vue3
的API
设计是Composition
(组合)风格的。
# Options API 的弊端
在 Vue2
中,API 设计采用了 Options API
风格。这种风格的代码组织方式虽然直观,但也存在一些问题:
- 分散性:数据、方法、计算属性等分别定义在
data
、methods
、computed
中。若需新增或修改功能,开发者需要在不同的选项块中进行修改,代码分散,不利于维护。 - 可复用性低:每个组件都是一个独立的对象,代码复用主要通过混入(mixins)实现,但混入在使用过程中可能会引入命名冲突等问题。
- 模块化困难:随着应用复杂度的增加,组件内的逻辑变得复杂,难以模块化和组织。
# Composition API 的优势
Vue3
中引入的 Composition API
,为开发者提供了一种新的代码组织方式,其主要优势包括:
- 模块化:通过函数来组织代码,将相关功能聚合在一起,使代码更为清晰,易于阅读和维护。
- 复用性强:借助
Composition API
,可以轻松将逻辑封装成可复用的函数,不必依赖于混入。 - 灵活性高:提供了对响应式状态更细粒度的控制,可以更加灵活地使用 Vue 的特性。
- 代码更优雅:相关功能的代码可以在一起组织,不需要在
data
、methods
、computed
等选项块之间跳转。
说明:以上四张动图原创作者:大帅老猿
# 2.【拉开序幕的 setup】
# setup 概述
setup
是Vue3
中一个新的配置项,值是一个函数,它是 Composition API
“表演的舞台”,组件中所用到的:数据、方法、计算属性、监视......等等,均配置在setup
中。
特点如下:
- 返回值的使用:
setup
函数返回的对象中的属性和方法可以直接在模板中使用。 - 没有
this
:在setup
函数中,this
是undefined
。这意味着在setup
中不能直接使用组件实例的属性或方法。 - 执行时机:
setup
函数会在beforeCreate
之前调用,是组件中最先执行的代码。
下面是一个使用 setup
函数的简单示例:
<template>
<div class="person">
<h2>姓名:{{name}}</h2>
<h2>年龄:{{age}}</h2>
<button @click="changeName">修改名字</button>
<button @click="changeAge">年龄+1</button>
<button @click="showTel">点我查看联系方式</button>
</div>
</template>
<script lang="ts">
export default {
name:'Person',
setup(){
// 数据,原来写在data中(注意:此时的name、age、tel数据都不是响应式数据)
let name = '张三'
let age = 18
let tel = '13888888888'
// 方法,原来写在methods中
function changeName(){
name = 'zhang-san' //注意:此时这么修改name页面是不变化的
console.log(name)
}
function changeAge(){
age += 1 //注意:此时这么修改age页面是不变化的
console.log(age)
}
function showTel(){
alert(tel)
}
// 返回一个对象,对象中的内容,模板中可以直接使用
return {name,age,tel,changeName,changeAge,showTel}
}
}
</script>
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
35
36
37
# setup 的返回值
- 返回对象:如果
setup
返回一个对象,对象中的属性和方法可以直接在模板中使用**(重点关注)**。
setup() {
let count = 0; // 属性
function increment() { // 方法
count++;
}
return { count, increment }; // 返回对象
}
2
3
4
5
6
7
8
9
- 返回函数:如果
setup
返回一个函数,该函数会替代组件的模板渲染。这种情况不常见,但在某些自定义渲染逻辑中可能会用到。
setup() {
return () => '你好啊!'; // 返回函数,自定义渲染内容
}
2
3
# setup 与 Options API 的关系
Vue2
的配置(data
、methos
......)中可以访问到setup
中的属性、方法。- 但在
setup
中不能访问到Vue2
的配置(data
、methos
......)。 - 如果与
Vue2
的配置冲突,则以setup
优先。
# setup 语法糖
setup
函数有一个语法糖,这个语法糖,可以让我们把setup
独立出去,代码如下:
<template>
<div class="person">
<h2>姓名:{{name}}</h2>
<h2>年龄:{{age}}</h2>
<button @click="changName">修改名字</button>
<button @click="changAge">年龄+1</button>
<button @click="showTel">点我查看联系方式</button>
</div>
</template>
<script lang="ts">
export default {
name:'Person',
}
</script>
<!-- 下面的写法是setup语法糖 -->
<script setup lang="ts">
console.log(this) //undefined
// 数据(注意:此时的name、age、tel都不是响应式数据)
let name = '张三'
let age = 18
let tel = '13888888888'
// 方法
function changName(){
name = '李四'//注意:此时这么修改name页面是不变化的
}
function changAge(){
console.log(age)
age += 1 //注意:此时这么修改age页面是不变化的
}
function showTel(){
alert(tel)
}
</script>
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
35
36
37
# 使用插件简化 setup
在 Vue3 项目中,<script setup>
是一种用于编写组件逻辑的简化语法。通常,我们需要通过 default export
的方式为组件指定名称,例如:
<script setup lang="ts">
// 组件逻辑
</script>
<script lang="ts">
export default {
name: 'Person'
}
</script>
2
3
4
5
6
7
8
9
这种方式需要写两段 <script>
标签,一段用于 setup
逻辑,另一段用于 default export
以指定组件名称。这可能会显得有些冗余。
# 插件的作用
vite-plugin-vue-setup-extend
插件可以让你直接在 <script setup>
标签中使用 name
属性来定义组件的名称,从而省去单独的 default export
语法。这使得代码更加简洁:
<script setup lang="ts" name="Person">
// 组件逻辑
</script>
2
3
通过这种方式,你可以在一个 <script setup>
标签内同时定义组件的逻辑和名称,减少了冗余代码,使代码更加清晰和直观。
# 安装插件
在 Vite 项目中,可以使用 vite-plugin-vue-setup-extend
插件来简化 setup
中组件名称的定义。
安装插件:
npm install vite-plugin-vue-setup-extend -D
1配置插件:
在
vite.config.ts
中添加插件:import { defineConfig } from 'vite'; import VueSetupExtend from 'vite-plugin-vue-setup-extend'; export default defineConfig({ plugins: [VueSetupExtend()] });
1
2
3
4
5
6使用语法糖定义组件名称:
<script setup lang="ts" name="Person"> // 组件逻辑 </script>
1
2
3
# 使用插件功能
现在你可以在 <script setup>
标签中直接使用 name
属性来定义组件名称:
<template>
<div class="person">
<h2>姓名:{{ name }}</h2>
<h2>年龄:{{ age }}</h2>
<button @click="changeName">修改名字</button>
<button @click="changeAge">年龄+1</button>
<button @click="showTel">点我查看联系方式</button>
</div>
</template>
<script setup lang="ts" name="Person">
let name = '张三';
let age = 18;
let tel = '13888888888';
function changeName() {
name = '李四';
}
function changeAge() {
age += 1;
}
function showTel() {
alert(tel);
}
</script>
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
使用插件后,整个组件的逻辑和名称定义可以集中在一个 <script setup>
标签中,从而提高代码的可读性和维护性。