Vue.js 3.0组合式API深度实践
Vue 3新特性
Vue 3带来了革命性的变化:组合式API、更好的TypeScript支持、更快的渲染性能和更小的打包体积。
Vue 2 vs Vue 3
| 特性 | Vue 2 | Vue 3 |
|---|---|---|
| API风格 | 选项式API | 组合式API |
| 响应式 | Object.defineProperty | Proxy |
| TypeScript | 支持有限 | 原生支持 |
| Fragments | 不支持 | 支持多根节点 |
| Teleport | 不支持 | 支持 |
组合式API基础
setup函数
Count: {{ count }}
响应式API
import { ref, reactive, toRef, toRefs, shallowRef, shallowReactive } from 'vue';
// ref - 用于基本类型(也可用于对象)
const count = ref(0);
count.value++; // 需要.value访问
// reactive - 用于对象/数组
const user = reactive({
name: 'Alice',
age: 25
});
user.age++; // 直接访问
// toRef - 将reactive属性转为ref
const nameRef = toRef(user, 'name');
// toRefs - 解构reactive对象
const { name, age } = toRefs(user);
// shallowRef/shallowReactive - 浅层响应式
const shallowUser = shallowRef({ name: 'Bob' });
// 只追踪.value的变化,不追踪内部属性
// readonly - 只读
const readonlyUser = readonly(user);
组合式函数
自定义Hook
// composables/useCounter.js
import { ref, computed } from 'vue';
export function useCounter(initialValue = 0) {
const count = ref(initialValue);
const doubleCount = computed(() => count.value * 2);
function increment() {
count.value++;
}
function decrement() {
count.value--;
}
function reset() {
count.value = initialValue;
}
return {
count,
doubleCount,
increment,
decrement,
reset
};
}
// 使用
import { useCounter } from './composables/useCounter';
setup() {
const { count, increment } = useCounter(10);
return { count, increment };
}
API请求Hook
// composables/useFetch.js
import { ref, watchEffect } from 'vue';
export function useFetch(url) {
const data = ref(null);
const error = ref(null);
const loading = ref(false);
async function fetchData() {
loading.value = true;
error.value = null;
try {
const response = await fetch(url.value);
if (!response.ok) throw new Error('Network error');
data.value = await response.json();
} catch (e) {
error.value = e;
} finally {
loading.value = false;
}
}
if (url.value) fetchData();
// 响应式URL变化时重新获取
watchEffect(() => {
if (url.value) fetchData();
});
return { data, error, loading, refetch: fetchData };
}
// 使用
import { useFetch } from './composables/useFetch';
setup() {
const userId = ref(1);
const url = computed(() => `/api/users/${userId.value}`);
const { data: user, loading, error } = useFetch(url);
return { user, loading, error, userId };
}
生命周期
import {
onBeforeMount,
onMounted,
onBeforeUpdate,
onUpdated,
onBeforeUnmount,
onUnmounted,
onErrorCaptured
} from 'vue';
export default {
setup() {
onBeforeMount(() => {
console.log('Before mount');
});
onMounted(() => {
console.log('Mounted');
// DOM已可用
});
onBeforeUpdate(() => {
console.log('Before update');
});
onUpdated(() => {
console.log('Updated');
});
onBeforeUnmount(() => {
console.log('Before unmount');
// 清理定时器、事件监听等
});
onUnmounted(() => {
console.log('Unmounted');
});
onErrorCaptured((err, instance, info) => {
console.error('Error captured:', err);
return false; // 阻止错误继续传播
});
}
};
依赖注入
// 父组件 - 提供依赖
import { provide, ref } from 'vue';
export default {
setup() {
const theme = ref('dark');
const user = ref({ name: 'Alice' });
provide('theme', theme);
provide('user', user);
provide('updateTheme', (newTheme) => {
theme.value = newTheme;
});
return { theme, user };
}
};
// 子组件 - 注入依赖
import { inject } from 'vue';
export default {
setup() {
const theme = inject('theme', 'light'); // 默认值
const user = inject('user');
const updateTheme = inject('updateTheme');
return { theme, user, updateTheme };
}
};
Teleport组件
最佳实践
- 优先使用组合式API:更好的代码组织和复用
- 合理命名composables:useXxx命名约定
- 解耦组件逻辑:将复杂逻辑提取到composables
- 使用TypeScript:获得完整类型支持
- 避免过度使用reactive:简单数据用ref
Vue 3的组合式API是现代Vue开发的最佳选择,掌握它能够构建更可维护的应用。
本文链接:https://www.kkkliao.cn/?id=757 转载需授权!
版权声明:本文由廖万里的博客发布,如需转载请注明出处。



手机流量卡
免费领卡
号卡合伙人
产品服务
关于本站
