The Best Fluffy Pancakes recipe you will fall in love with. Full of tips and tricks to help you make the best pancakes.
今天修改專案時,想說把ajax的過程用一個loading的過場鎖住畫面以防資料擷取的時候使用者做了其他操作而產生預期外的問題
所以想說製作一個全畫面的mask,然後希望可以全域引入,盡量減少在我要使用的地方所需要的程式碼
以下gpt回應
在這個範例中,如果要從外部控制遮罩的顯示與隱藏,可以將狀態和方法提取到一個可復用的組合式函數中,並在應用的入口文件中進行全局注入。這樣就可以在任何地方使用 showReload
和 hideReload
來控制遮罩顯示或隱藏。
以下是修改後的實現方式:
1. 建立 useReload
組合式函數
建立一個 useReload.js
文件,用來控制 visible
狀態,並提供顯示與隱藏的方法。
composables/useReload.js
:
javascript複製程式碼import { reactive } from 'vue';
const state = reactive({
visible: false,
});
export const showReload = () => {
state.visible = true;
};
export const hideReload = () => {
state.visible = false;
};
export const useReload = () => {
return { state, showReload, hideReload };
};
2. 調整遮罩組件
遮罩組件直接使用 useReload
中的 state
來控制顯示邏輯。
components/GlobalReload.vue
:
vue複製程式碼<script setup>
import { useReload } from '../composables/useReload';
const { state } = useReload();
</script>
<template>
<teleport to="body">
<div v-if="state.visible" class="reload-mask">
<div class="spinner"></div>
</div>
</teleport>
</template>
<style scoped>
.reload-mask {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
}
.spinner {
border: 5px solid rgba(255, 255, 255, 0.3);
border-top: 5px solid white;
border-radius: 50%;
width: 40px;
height: 40px;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>
3. 在主應用中全局注入 showReload
和 hideReload
在 main.js
中引入 showReload
和 hideReload
,並注入到 Vue 全局中,使得任何組件都可以直接使用這兩個方法。
main.js
:
javascript複製程式碼import { createApp } from 'vue';
import App from './App.vue';
import GlobalReload from './components/GlobalReload.vue';
import { showReload, hideReload } from './composables/useReload';
const app = createApp(App);
// 全局注入遮罩控制方法
app.config.globalProperties.$showReload = showReload;
app.config.globalProperties.$hideReload = hideReload;
app.component('GlobalReload', GlobalReload);
app.mount('#app');
4. 在任何組件中呼叫遮罩控制方法
現在可以在任何組件的 setup
函數中,透過 this.$showReload()
和 this.$hideReload()
來控制遮罩的顯示和隱藏。
例如:
javascript複製程式碼<script setup>
import { getCurrentInstance, onMounted } from 'vue';
const { proxy } = getCurrentInstance();
onMounted(async () => {
proxy.$showReload();
try {
// 模擬一個異步操作
await new Promise(resolve => setTimeout(resolve, 2000));
} finally {
proxy.$hideReload();
}
});
</script>
實作結果
照著ai給的步驟造著做,確實達到了我想要的效果
但是在需要使用的頁面中都至少要使用四行程式碼
import { getCurrentInstance } from 'vue'
const { proxy } = getCurrentInstance();
proxy.$showLoading();
proxy.$hideLoading();
感覺這樣用跟我直接在頁面中宣告boolean變數,然後以props的方式傳入控制差異不大,不過學了一個teleport的新概念也是不錯,希望未來能找到更好的應用時機