高效开发:VueUse常用Hook的应用与实践
dave
26 Aug 2024
VueUse 是一个面向 Vue 3 的功能丰富的工具库,提供了众多 Composition API 函数,旨在简化开发过程中常见任务的处理。以下是其一些实用的 Hook 及其应用实例,演示如何通过这些工具提升开发效率:
useStorage
利用useStorage可以更简便地进行本地存储操作,并实现响应式数据存取。
使用前:
window.localStorage.setItem('rememberUserName', 'true');
const remember = window.localStorage.getItem('rememberUserName');
if (remember === 'true') {
// ...
}
window.addEventListener('storage', () => {
// ...
}, false);
使用后:
const remember = useStorage('rememberUserName', '', window.localStorage);
remember.value = true;
if (remember.value) {
// ...
}
watch(
() => remember.value,
(newVal) => {
// ...
}
);
useAsyncState
useAsyncState适用于处理异步操作,如 API 数据请求,并在数据返回前显示加载状态。
使用前:
type StateType = string[];
const state = ref<StateType>();
const isLoading = ref(false);
async function fetchData() {
isLoading.value = true;
try {
const { data } = await request.get<StateType>('tags');
state.value = data;
} finally {
isLoading.value = false;
}
}
使用后:
type StateType = string[];
async function fetchData() {
const { data } = await request.get<StateType>('tags');
return data;
}
const { state, isLoading } = useAsyncState(fetchData, [] as StateType);
有时候我们可能只需要在执行异步任务时获取当前任务loading状态,可以基于useAsyncState做一下封装。
const useAsync = <Data>(
promise: Promise<Data> | ((...args: any[]) => Promise<Data>),
initialState?: Data
) => {
return useAsyncState(promise, initialState, { immediate: false });
};
async function handleFormSubmit() {
await request.post('form');
}
const { execute: formSubmitExec, isLoading: formSubmitLoading } = useAsync(handleFormSubmit);
formSubmitExec();
useMounted
用useMounted检测组件挂载状态,常用于在组件和相关功能就绪后执行某些操作。
const isMounted = useMounted();
const funcReady = ref(false);
watch(
() => [isMounted.value, funcReady.value],
() => {
if (isMounted.value && funcReady.value) {
// ...
}
}
)
useBreakpoints
用useBreakpoints基于断点的响应式设计,根据屏幕大小执行特定逻辑。
const { smallerOrEqual } = useBreakpoints({
'sm': 640,
'md': 1024,
'lg': 1280,
'xl': 1536,
'2xl': 1920,
});
const isSmallScreen = smallerOrEqual('sm');
watch(
() => isSmallScreen.value,
(newVal) => {
if (newVal) {
// ...
}
}
)
useStepper
用useStepper实现分步骤表单或向导。
const {
goToPrevious,
goToNext,
isFirst,
isLast,
current,
} = useStepper([
'step-1',
'step-2',
'step-3'
]);
function handleSubmit() {
// ...
}
HTML 示例:
<div class="step-1" v-if="current === 'step-1'">
step-1
</div>
<div class="step-1" v-if="current === 'step-2'">
step-2
</div>
<div class="step-1" v-if="current === 'step-3'">
step-3
</div>
<button v-if="!isFirst" @click="goToPrevious">上一步</button>
<button v-if="isLast" @click="handleSubmit">提交</button>
<button v-else @click="goToNext">下一步</button>
useFileDialog
用useFileDialog简化文件选择对话框的使用,尤其是在处理文件输入样式重置时。
const { open, onChange } = useFileDialog({
accept: '.jpeg,.jpg,.png',
multiple: false,
reset: true,
});
onChange(files => {
// ...
})
HTML 示例:
<button @click="open()">选择文件</button>
useScrollLock
用useScrollLock防止页面滚动,如在弹窗打开时。
const el = ref<HTMLElement | null>(null)
const isLocked = useScrollLock(el);
function onDialogOpen() {
el.value = document.querySelector('.scroll-container');
isLocked.value = true;
}
useScroll
用useScroll监控元素的滚动事件,如实现滚动到底部加载更多内容.
const el = ref<HTMLElement | null>(null)
onMounted(() => {
el.value = document.querySelector('.scroll-container');
});
const scrollState = useScroll(el, {
offset: {
bottom: 50,
},
onScroll() {
if (scrollState.arrivedState.bottom) {
// ...
}
}
});
useClipboard
用useClipboard简化复制到剪切板的操作。
const { copy, copied } = useClipboard();
HTML 示例:
<span v-if="copied">Copied</span>
<button @click="copy()">Copy</button>
以上是 VueUse 常用 Hook 的一些应用实例,通过这些例子可以看出,VueUse 极大地简化了 Vue 3 中常见的功能实现,使得代码更加简洁,逻辑更清晰,从而提升开发效率。
Tags
Vue
VueUse