跳转至

Vue3组合式API实战:构建更可维护的组件 - 代码组织与复用技巧

原文地址: https://88box.top 生成时间: 2026-05-21 01:03:52


Vue3组合式API实战:构建更可维护的组件 - hey99 知识搜索引擎

精选文章

Vue3组合式API实战:构建更可维护的组件

/ Options API - 按选项组织代码data() {return {count: 0,name: '蔓蔓'},methods: {},// Composition API - 按功能组织代码setup() {const name = ref('蔓蔓');更好的代码组织 - 按功能组织代码更好的代码复用 - 通过组合式函数复用逻辑更好的类型推断 - 更好的TypeScript支持更小的打包体积 - 按需导入。

更新于 2026-05-20 16:37

webpack

前端

vue.js

javascript

ecmascript

Vue3组合式API实战:构建更可维护的组件

大家好,我是蔓蔓。Vue3的组合式API是一个非常强大的特性,它让我们能够更好地组织和复用代码。今天我来和大家分享Vue3组合式API的实战技巧。

什么是组合式API

Options API vs Composition API

// Options API - 按选项组织代码

export default {

data() {

return {

count: 0,

name: '蔓蔓'

};

},

methods: {

increment() {

this.count++;

}

},

computed: {

doubleCount() {

return this.count * 2;

}

}

};

// Composition API - 按功能组织代码

import { ref, computed } from 'vue';

export default {

setup() {

const count = ref(0);

const name = ref('蔓蔓');

const increment = () => {

count.value++;

};

const doubleCount = computed(() => count.value * 2);

return { count, name, increment, doubleCount };

}

};

响应式基础

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

// ref - 用于基本类型

const count = ref(0);

count.value++; // 需要.value访问

// reactive - 用于对象

const state = reactive({

name: '蔓蔓',

age: 25

});

state.name = '新名字'; // 直接访问

// computed - 计算属性

const doubleCount = computed(() => count.value * 2);

// watch - 监听变化

watch(count, (newVal, oldVal) => {

console.log(count changed from ${oldVal} to ${newVal});

});

// watchEffect - 自动追踪依赖

watchEffect(() => {

console.log(count is: ${count.value});

});

实战案例

组合式函数

// useCounter.js - 可复用的组合式函数

import { ref, computed } from 'vue';

export function useCounter(initialValue = 0) {

const count = ref(initialValue);

const increment = () => {

count.value++;

};

const decrement = () => {

count.value--;

};

const reset = () => {

count.value = initialValue;

};

const doubleCount = computed(() => count.value * 2);

return {

count,

increment,

decrement,

reset,

doubleCount

};

}

// 使用

import { useCounter } from './useCounter';

export default {

setup() {

const { count, increment, doubleCount } = useCounter(10);

return { count, increment, doubleCount };

}

};

异步数据获取

// useFetch.js - 数据获取组合式函数

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

export function useFetch(url, options = {}) {

const data = ref(null);

const error = ref(null);

const loading = ref(true);

let controller = null;

const fetchData = async () => {

loading.value = true;

error.value = null;

controller = new AbortController();

try {

const response = await fetch(url, {

...options,

signal: controller.signal

});

if (!response.ok) {

throw new Error(HTTP ${response.status});

}

data.value = await response.json();

} catch (err) {

if (err.name !== 'AbortError') {

error.value = err.message;

}

} finally {

loading.value = false;

}

};

onMounted(fetchData);

onUnmounted(() => {

if (controller) {

controller.abort();

}

});

return {

data,

error,

loading,

refetch: fetchData

};

}

// 使用

import { useFetch } from './useFetch';

export default {

setup() {

const { data: user, loading, error } = useFetch('/api/user');

return { user, loading, error };

}

};

表单处理

// useForm.js - 表单处理组合式函数

import { reactive, computed } from 'vue';

export function useForm(initialValues) {

const form = reactive({ ...initialValues });

const errors = reactive({});

const validateField = (fieldName, rules) => {

errors[fieldName] = null;

for (const rule of rules) {

if (rule.required && !form[fieldName]) {

errors[fieldName] = rule.message || '此字段必填';

return false;

}

if (rule.pattern && !rule.pattern.test(form[fieldName])) {

errors[fieldName] = rule.message || '格式不正确';

return false;

}

}

return true;

};

const validate = (fieldRules) => {

let isValid = true;

for (const [fieldName, rules] of Object.entries(fieldRules)) {

if (!validateField(fieldName, rules)) {

isValid = false;

}

}

return isValid;

};

const reset = () => {

Object.assign(form, initialValues);

Object.keys(errors).forEach(key => delete errors[key]);

};

const isValid = computed(() => {

return Object.keys(errors).length === 0;

});

return {

form,

errors,

validateField,

validate,

reset,

isValid

};

}

// 使用

import { useForm } from './useForm';

export default {

setup() {

const { form, errors, validate } = useForm({

email: '',

password: ''

});

const rules = {

email: [

{ required: true, message: '邮箱必填' },

{ pattern: /^[^\s@]+@[^\s@]+.[^\s@]+$/, message: '请输入有效邮箱' }

],

password: [

{ required: true, message: '密码必填' },

{ pattern: /.{6,}/, message: '密码至少6位' }

]

};

const handleSubmit = () => {

if (validate(rules)) {

console.log('Form submitted:', form);

}

};

return { form, errors, handleSubmit };

}

};

高级技巧

依赖注入

// 父组件提供数据

import { provide } from 'vue';

export default {

setup() {

const theme = ref('dark');

provide('theme', theme);

provide('toggleTheme', () => {

theme.value = theme.value === 'dark' ? 'light' : 'dark';

});

}

};

// 子组件注入数据

import { inject } from 'vue';

export default {

setup() {

const theme = inject('theme');

const toggleTheme = inject('toggleTheme');

return { theme, toggleTheme };

}

};

生命周期钩子

import { onMounted, onUnmounted, onUpdated, onBeforeMount, onBeforeUpdate, onBeforeUnmount } from 'vue';

export default {

setup() {

onBeforeMount(() => {

console.log('组件挂载前');

});

onMounted(() => {

console.log('组件挂载完成');

});

onBeforeUpdate(() => {

console.log('组件更新前');

});

onUpdated(() => {

console.log('组件更新完成');

});

onBeforeUnmount(() => {

console.log('组件卸载前');

});

onUnmounted(() => {

console.log('组件卸载完成');

});

}

};

总结

Vue3的组合式API带来了很多好处:

更好的代码组织 - 按功能组织代码

更好的代码复用 - 通过组合式函数复用逻辑

更好的类型推断 - 更好的TypeScript支持

更小的打包体积 - 按需导入

技术应当有温度,好的代码结构能提升开发体验。

查看原文


🏷 标签: Vue3, 组合式API, TypeScript, 前端工程化, 响应式编程