Vue3 Composition API实战教程


Vue3 Composition API实战教程

Vue3引入的Composition API是对Vue2 Options API的一次重大革新。它提供了更灵活的代码组织方式,使逻辑复用更加简单,TypeScript支持更加完善。本文将通过实际案例带你全面掌握Composition API的使用方法。

一、为什么需要Composition API

在Vue2的Options API中,一个组件的逻辑被分散在data、computed、methods、watch等选项中。当组件变得复杂时,相关的逻辑代码被拆分到不同的位置,导致代码难以维护。

Composition API允许我们按照逻辑功能来组织代码,而不是按照选项类型。相关功能的代码可以集中在一起,形成可复用的"组合式函数"。

二、setup函数与响应式基础

setup是Composition API的入口函数,在组件创建之前执行。它接收props和context两个参数:

export default {
    setup(props, context) {
        // 响应式数据
        const count = ref(0);
        
        // 计算属性
        const doubleCount = computed(() => count.value * 2);
        
        // 方法
        function increment() {
            count.value++;
        }
        
        // 暴露给模板
        return {
            count,
            doubleCount,
            increment
        };
    }
}

ref与reactive的区别

ref用于基本类型数据,通过.value访问值。reactive用于对象类型数据,直接访问属性:

import { ref, reactive } from 'vue';

// ref - 适用于基本类型
const count = ref(0);
count.value++;

// reactive - 适用于对象
const user = reactive({
    name: '张三',
    age: 25
});
user.age = 26;  // 直接访问

三、生命周期钩子

在setup中,生命周期钩子以on前缀的函数形式使用:

import { onMounted, onUnmounted, onUpdated } from 'vue';

setup() {
    onMounted(() => {
        console.log('组件已挂载');
        // 初始化数据、绑定事件等
    });
    
    onUpdated(() => {
        console.log('组件已更新');
    });
    
    onUnmounted(() => {
        console.log('组件已卸载');
        // 清理定时器、取消事件绑定等
    });
}

四、自定义组合式函数(Composables)

这是Composition API最强大的特性,它允许我们将逻辑提取为可复用的函数:

// useMousePosition.js
import { ref, onMounted, onUnmounted } from 'vue';

export function useMousePosition() {
    const x = ref(0);
    const y = ref(0);
    
    function update(event) {
        x.value = event.pageX;
        y.value = event.pageY;
    }
    
    onMounted(() => window.addEventListener('mousemove', update));
    onUnmounted(() => window.removeEventListener('mousemove', update));
    
    return { x, y };
}

// 在组件中使用
import { useMousePosition } from './useMousePosition';

setup() {
    const { x, y } = useMousePosition();
    return { x, y };
}

五、watch与watchEffect

watch用于监听特定数据源的变化,watchEffect则自动追踪依赖:

import { ref, watch, watchEffect } from 'vue';

const keyword = ref('');

// watch - 明确指定监听目标
watch(keyword, (newVal, oldVal) => {
    console.log('关键词从', oldVal, '变为', newVal);
    // 执行搜索
});

// watchEffect - 自动追踪依赖
watchEffect(() => {
    console.log('当前关键词:', keyword.value);
    // 自动依赖追踪
});

六、实际项目示例:待办事项管理

// useTodoList.js
import { ref, computed } from 'vue';

export function useTodoList() {
    const todos = ref([]);
    const filter = ref('all');
    
    const filteredTodos = computed(() => {
        switch (filter.value) {
            case 'done': return todos.value.filter(t => t.done);
            case 'undone': return todos.value.filter(t => !t.done);
            default: return todos.value;
        }
    });
    
    const stats = computed(() => ({
        total: todos.value.length,
        done: todos.value.filter(t => t.done).length,
        pending: todos.value.filter(t => !t.done).length
    }));
    
    function addTodo(text) {
        todos.value.push({
            id: Date.now(),
            text,
            done: false
        });
    }
    
    function toggleTodo(id) {
        const todo = todos.value.find(t => t.id === id);
        if (todo) todo.done = !todo.done;
    }
    
    function removeTodo(id) {
        todos.value = todos.value.filter(t => t.id !== id);
    }
    
    return {
        todos: filteredTodos,
        filter,
        stats,
        addTodo,
        toggleTodo,
        removeTodo
    };
}

七、性能优化建议

使用Composition API时,有几个性能优化的最佳实践:

  • 使用shallowRef和shallowReactive处理大型数据结构
  • 避免在模板中直接调用函数,使用computed缓存结果
  • 使用watch的flush: 'post'选项来避免不必要的DOM更新
  • 对于不需要响应式的数据,使用markRaw标记

Composition API代表了Vue3的核心思想,它不仅提供了更好的代码组织方式,还为大型应用的可维护性和可扩展性奠定了基础。通过合理使用组合式函数,可以显著提高代码的复用率和可读性。


0.069605s