预加载 Element Plus 的 Dialog 组件
对于 Element Plus 的 Dialog 组件,浏览器调试发现,正常使用 Dialog 组件时,它的蒙层和模态框元素会随页面初始加载完毕,但模态框内部的元素却只有在首次显示时浏览器再去渲染。
如果 Dialog 组件的内容很多,首次加载比较耗时(3 秒以上),那交互体验必定不好。如果我们在恰当的时机去提前加载该组件,那么用户首次打开时,浏览器就不用才开始渲染 Dialog 组件内容。
分析
最直接的方案就是在页面挂载并拿到数据后,主动触发渲染但不显示 Dialog 组件,然后再关闭隐藏。这样,用户之后点击打开 Dialog 的时候,无需等待太久。
思路
- Dialog 组件先设置为不可见(
display:none !important
) - 监听 Dialog 组件的绑定变量,首次显示后,标记已预加载过
- 再次显示后,移除上一步的监听,并将 Dialog 组件设置为可见
尝试过在首次显示后执行第三步,精简流程。但“隐藏组件”与“设置组件可见”的时序不好控制,会导致手动加载的 dialog 闪现。
方案
上代码,演练场试下:preload dialog
vue
<script setup>
import { ref, onMounted, watch, nextTick } from 'vue'
const data = ref('')
const visible = ref(false)
onMounted(async () => {
data.value = await getData()
preloadComp()
})
function getData() {
// fetch data
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(Math.floor(Math.random()*900000+100000).toString(16))
}, 500)
})
}
let preloaded = false
const preloadWatcher = watch(visible, newVal => {
if (newVal) {
if (!preloaded) {
preloaded = true
} else {
// 完成预加载任务,不再监听
resolvedPreload()
preloadWatcher()
}
}
})
// 完成预加载任务
function resolvedPreload() {
// 移除类
document.querySelector('.preload-block').classList.remove('preload-block')
}
function preloadComp() {
visible.value = true
nextTick(() => {
visible.value = false
})
}
</script>
<template>
<el-button @click="visible = true">Show Prevload Dialog</el-button>
<!-- Preload Dialog -->
<el-dialog title="Preload Dialog" v-model="visible" width="550px" modal-class="preload-block">
<div>Data: {{ data }}</div>
</el-dialog>
</template>
<style>
.preload-block {
display: none !important;
}
</style>
通过 modal-class
属性给 Dialog 添加类,设置初始不可见。然后如上一节一样,在页面挂载并获取到数据后,预加载 Dialog,完成后移除类 prevload-block
。不影响后续使用。
这种实现方案要求必须执行手动加载方法一次,否则类 prevload-block
永远不会被移除,dialog组件一直不可见。
Last updated: