选项式API(Options API)
1. 定义:选项式API 是 Vue 2 和 Vue 3 都支持的传统写法,它通过不同的选项 options(如:data、methods、computed、watch、生命周期等)来组织代码。
2. 特点:
-
按功能分类:数据放在
data,方法放在methods,计算属性放在computed,生命周期放在mounted等。 -
自动响应式:
data()返回的对象会自动变成响应式。 -
依赖
this:访问数据和方法需要使用this。 - 适合简单组件:逻辑较少时,代码结构清晰。
3. 示例:
<template>
<button @click="handleClick">Count: {{ count }}</button>
</template>
<script>
export default {
data() {
return { count: 0 } // 自动响应式
},
methods: {
handleClick() {
this.count++ // 必须用 this
}
},
mounted() {
console.log("组件已加载")
}
}
</script>
组合式API (Composition API)
1.定义:组合式API 是 Vue 3 引入的新写法,它使用 setup() 函数(或 <script setup> 语法糖)来组织代码,可以更灵活地按逻辑功能组织代码,而不是按选项分类。
2.特点:
- 按逻辑组织:相关代码(如数据 + 方法 + 计算属性)可以写在一起,而不是分散在不同选项里。
- 显式响应式:需要使用 ref 或 reactive 手动声明响应式数据。
-
无
this:直接使用变量和函数,不需要this。 -
更好的代码复用:可以使用
composables(自定义逻辑函数)来复用代码。 - 更好的 TypeScript 支持:类型推断更友好。
3.示例
- 写法1:标准写法
<template>
<button @click="handleClick">Count: {{ count }}</button>
</template>
<script>
import { ref } from "vue"
export default {
setup() {
const count = ref(0) // 手动声明响应式数据
const handleClick = () => {
count.value++ // 注意要用 .value
}
return { count, handleClick } // 暴露给模板
}
}
</script>
写法2(推荐):语法糖写法 <script setup>
<template>
<button @click="handleClick">Count: {{ count }}</button>
</template>
<script setup>
import { ref } from "vue"
const count = ref(0) // 响应式数据
const handleClick = () => count.value++ // 方法
</script>
核心区别总结:
| 特性 | 选项式API | 组合式API |
|---|---|---|
| 代码组织 | 按选项类型组织(data/methods等) | 按逻辑功能组织 |
| 响应式数据 | 自动响应式(data返回的对象) | 需显式使用ref/reactive |
| this使用 | 必须使用this访问数据和方法 | 不需要使用this |
| 逻辑代码复用 | 使用 mixins(混入) | 使用 composables(组合式函数) |
| TypeScript支持 | 一般 | 更好 |
| 逻辑关注点 | 分散在不同选项中 | 集中在一起 |
代码复用/逻辑封装
1.Mixins(混入):
定义:Mixins 是 Vue 2 中的一种代码复用机制,允许你将一组组件选项(如 data、methods、生命周期钩子 等)封装成一个独立模块,然后通过 mixins 选项将其“混入”到多个组件中。
通俗理解:就像把一段通用的代码“复制粘贴”到多个组件里,让它们共享相同的逻辑。
示例:
- 定义一个 mixin(即将部分逻辑代码单独封装)
// mixins/counterMixin.js
export default {
data() {
return {
count: 0,
};
},
methods: {
handleClick() {
this.count++;
},
},
};
- 在组件中使用 mixin
<template>
<!-- 可以直接使用 mixin 的数据和方法 -->
<button @click="handleClick">Count: {{ count }}</button>
</template>
<script>
import counterMixin from "./mixins/counterMixin";
export default {
mixins: [counterMixin], // 混入(是一种代码复用方式。混入后,其他地方就可以直接使用 mixin 的数据和方法)
mounted() {
console.log(this.count) // 可以直接使用 mixin 的数据和方法
}
};
</script>
⚠️ 问题:命名冲突
如果另一个 mixin 也定义了 count 或 handleClick,Vue 会合并它们,可能导致意外覆盖或逻辑混乱:
// mixins/anotherMixin.js
export default {
data() {
return {
count: 100, // 冲突!会覆盖 counterMixin 的 count
};
},
};
2. Composables(组合式函数)
定义:Composables 是 Vue 3 推荐的代码复用方式,它使用 组合式函数(Composable Functions) 来封装逻辑,让组件可以按需引入和组合逻辑。
通俗理解:像“拼乐高积木”一样,把不同的逻辑函数(如计数器、网络请求)自由组合到组件中,避免代码重复。
示例:
- 定义 composable
// composables/useCounter.js
import { ref } from "vue";
// 使用 组合式函数 封装代码逻辑,可以按需导入响应式数据和方法
export function useCounter(value = 0) {
const count = ref(value);
const handleClick = () => {
count.value++;
};
return { count, handleClick }; // 返回响应式数据和方法
}
- 在组件中使用 composable
<template>
<button @click="handleClick">Count: {{ count }}</button>
</template>
<script setup>
// 导入函数
import { useCounter } from "./composables/useCounter";
// 使用 composable:可以清晰地看到返回的 count 和 handleClick
const { count, handleClick } = useCounter(0); // 通过解构提取需要用到的数据或方法
</script>
✅ 优势:避免命名冲突
如果另一个 composable 也返回 count,我们可以重命名解构:
<script setup>
import { useCounter } from "./composables/useCounter";
import { useAnotherCounter } from "./composables/useAnotherCounter";
// 解构写法:如果不想用原属性名,可以重命名
const { count: count1, increment: increment1 } = useCounter(0);
const { count: count2, increment: increment2 } = useAnotherCounter(100);
// 可以同时使用,互不冲突!
</script>
解构(Destructuring)
解构是一种快速从 对象(Object) 或 数组(Array) 中提取数据并赋值给变量的语法,可以让代码更简洁直观。
总结:解构就是从对象或数组中“拆包”数据,像拆快递一样直接拿到你想要的部分,让代码更简洁!
- 对象的解构
/// 定义一个对象
const user = {
name: "小明",
age: 18,
city: "北京"
}
/// 用解构语法提取属性
// 1.传统写法(繁琐)
const name = user.name
const age = user.age
// 2.解构写法(简洁)
const { name, age } = user
console.log(name) // "小明"
console.log(age) // 18
// 重命名变量:如果不想用原属性名,可以重命名
const { name: userName, age: userAge } = user
console.log(userName) // "小明"(原属性名是 name)
- 数组的解构
/// 定义一个数组
const colors = ["红色", "绿色", "蓝色"]
/// 用解构提取元素
// 1.传统写法
const first = colors[0]
const second = colors[1]
// 2.解构写法
const [first, second] = colors
console.log(first) // "红色"
console.log(second) // "绿色"
// 跳过某些元素:用逗号跳过不需要的元素
const [first, , third] = colors
console.log(first); // "红色"
console.log(third); // "蓝色"(跳过了第二个元素)
- 核心区别
| 特性 | Mixins | Composables |
|---|---|---|
| 代码复用方式 | 混入(自动合并选项到组件) | 函数调用(显式按需引入) |
| 命名冲突 | 容易冲突(比如多个 mixin 同名数据) | 无冲突(可重命名解构) |
| 逻辑清晰度 | 隐式依赖(难追踪来源) | 显式导入(清晰可见) |
| 灵活性 | 固定选项(data/methods 等) | 自由组合(函数式编程) |
| 适用版本 | Vue 2 | Vue 3 |