1. 为什么要引入组合API
组合API是Vue 3中引入的一种新的编程模式,它将组件的逻辑分散到多个函数中,使得代码更加可读、可维护。通过引入组合API,可以解决Vue 2中使用Options API时遇到的一些问题,如代码复用性差、组件逻辑难以拆分等。
2. setup()函数
在Vue 3中,引入了setup()函数来声明组件的逻辑。在组件创建时,该函数会被调用,我们可以在该函数中进行一些初始化操作,并且返回一个包含模板中要使用的数据、方法等的对象。
代码案例:
<template> <div> <p>计数器:{{ count }}</p > <button @click="increment">增加</button> </div> </template> <script> import { ref } from 'vue'; export default { setup() { const count = ref(0); const increment = () => { count.value++; }; return { count, increment }; } }; </script>
代码运行结果:
计数器:0 增加按钮
代码分析:
在上述代码中,我们使用了setup()函数来初始化组件的数据和方法。
在setup()函数中,通过调用ref()创建了一个响应式的数据count,并设置初始值为0。
在increment函数中,我们通过count.value++来增加计数器的值。
最后,我们将count和increment作为返回值,使得在模板中可以使用count和increment。
3. 响应式API
在Vue 3中,提供了一系列的响应式API,用于管理和操作组件中的响应式数据。
代码案例:
<template> <div> <p>用户名:{{ user.name }}</p > <p>年龄:{{ user.age }}</p > <button @click="changeUser">更改用户</button> </div> </template> <script> import { reactive } from 'vue'; export default { setup() { const user = reactive({ name: 'Alice', age: 20 }); const changeUser = () => { user.name = 'Bob'; user.age = 25; }; return { user, changeUser }; } }; </script>
代码运行结果:
用户名:Alice 年龄:20 更改用户按钮
代码分析:
在上述代码中,我们使用了reactive()函数来创建一个响应式对象user,其中包含了name和age两个属性。
在changeUser函数中,我们通过修改user对象的属性来改变用户的姓名和年龄。
由于使用了响应式API,当user的属性发生变化时,页面上展示的数据也会自动更新。
3.1 reactive和watchEffect
在Vue中,我们可以使用reactive()函数来创建响应式对象,并使用watchEffect()函数来观察响应式数据的变化。
代码案例:
<template> <div> <p>计数器:{{ count }}</p > <button @click="increment">增加</button> </div> </template> <script> import { reactive, watchEffect } from 'vue'; export default { setup() { const state = reactive({ count: 0 }); const increment = () => { state.count++; }; watchEffect(() => { console.log('计数器变化:', state.count); }); return { count: state.count, increment }; } }; </script>
代码运行结果:
计数器:0 增加按钮 (点击增加按钮后,控制台输出:计数器变化:1)
代码分析:
在上述代码中,我们使用reactive()函数创建了一个响应式对象state,并在其中定义了一个count属性。
在increment方法中,我们通过state.count++来增加计数器的值。
使用watchEffect()函数来观察state.count的变化,并在变化时执行回调函数,此处简单地在控制台输出计数器的变化值。
最后,我们将state.count和increment作为返回值,以供模板中使用。
3.2 ref
在Vue中,我们可以使用ref()函数创建一个包装的容器,用于在组件中包裹一个简单值,并保持响应式。
代码案例:
<template> <div> <p>计数器:{{ count.value }}</p > <button @click="increment">增加</button> </div> </template> <script> import { ref } from 'vue'; export default { setup() { const count = ref(0); const increment = () => { count.value++; }; return { count, increment }; } }; </script>
代码运行结果:
计数器:0 增加按钮 (点击增加按钮后,计数器的值会随之增加)
代码分析:
在上述代码中,我们使用ref()函数创建了一个容器count,并初始化其值为0。
在increment方法中,我们通过count.value++来增加计数器的值。需要注意的是,由于count是ref容器,我们需要通过.count来访问实际的值。
最后,我们将count和increment作为返回值,以供模板中使用。
3.3 readonly
在Vue中,我们可以使用readonly()函数将一个对象或数组设置为只读,从而使其变为只读的响应式数据。
代码案例:
<template> <div> <p>只读数据:{{ message }}</p > </div> </template> <script> import { readonly } from 'vue'; export default { setup() { const data = readonly({ message: 'Hello Vue!' }); return { message: data.message }; } }; </script>
代码运行结果:
只读数据:Hello Vue!
代码分析:
在上述代码中,我们使用readonly()函数将一个对象data设置为只读的响应式数据。
在模板中,我们通过data.message来访问只读数据。
由于只读数据不可修改,所以我们不能在组件中直接修改data.message的值。
3.4 computed:
在Vue中,我们可以使用computed()函数创建一个计算属性,用于根据依赖的响应式数据进行计算。
代码案例:
<template> <div> <p>半径:{{ radius }}</p > <p>圆的面积:{{ area }}</p > </div> </template> <script> import { ref, computed } from 'vue'; export default { setup() { const radius = ref(5); const area = computed(() => { return Math.PI * radius.value * radius.value; }); return { radius, area }; } }; </script>
代码运行结果:
半径:5 圆的面积:78.54
代码分析:
在上述代码中,我们使用ref()函数创建了一个容器radius,并初始化其值为5。
使用computed()函数来创建一个计算属性area,其值是根据radius.value计算得出的圆的面积。
最后,我们将radius和area作为返回值,以供模板中使用。
3.5 watch
在Vue中,我们可以使用watch()函数来监听响应式数据的变化,并在变化时执行回调函数。
代码案例:
<template> <div> <p>用户名:{{ username }}</p > <p>年龄:{{ age }}</p > </div> </template> <script> import { ref, watch } from 'vue'; export default { setup() { const username = ref(''); const age = ref(0); watch([username, age], ([newUsername, newAge], [oldUsername, oldAge]) => { console.log('用户信息变化:', newUsername, newAge); }); return { username, age }; } }; </script>
代码运行结果:
用户名: 年龄: (当username和age发生变化时,控制台输出用户信息变化的内容)
代码分析:
在上述代码中,我们使用ref()函数分别创建了username和age两个容器,并初始化其初始值为空字符串和0。
使用watch()函数来监听username和age的变化,并在变化时执行回调函数,回调函数接收两个参数:新值和旧值。
在回调函数中,我们简单地在控制台输出用户信息的变化内容。
最后,我们将username和age作为返回值,以供模板中使用。
4. 生命周期钩子
Vue中的生命周期钩子函数用于在组件的不同生命周期阶段执行特定的逻辑。它们可以帮助我们在组件创建、更新和销毁的过程中做一些额外的操作。
5. 依赖注入
依赖注入是一种设计模式,用于提供组件之间的依赖关系。在Vue中,可以使用provide和inject方法来实现依赖注入,通过父组件提供数据,并在子组件中接收和使用这些数据。
6. 逻辑提取和重用
在开发过程中,我们经常会遇到需要重复使用的逻辑。Vue提供了mixin、自定义指令、插件等方法来实现逻辑的提取和重用,以便我们更高效地开发和维护代码。
7. 小结
在本章中,我们学习了Vue中的生命周期钩子、依赖注入和逻辑提取和重用的方法。生命周期钩子函数帮助我们在组件不同的生命周期阶段执行特定的逻辑,依赖注入提供了一种方便的方式来实现组件之间的数据传递,逻辑提取和重用通过mixin、自定义指令、插件等方法帮助我们更高效地开发和维护代码。