Vue 3 自定义指令 — 骨架屏
文章图片
前言
骨架屏是页面的一个空白版本,通常会在页面完全渲染之前,通过一些灰色的区块大致勾勒出轮廓,待数据加载完成后,再替换成真实的内容。
目前主流 UI库
都有骨架屏,如 Element-UI
、Antd
可以看到使用起来非常简单,只需要一行代码即可
// element
// antd
但这样不够灵活,对于追求个性化的页面就不太行了,
后来~ 我想了想,能不能给
节点
打 标记
,然后根据 标记
自动生成对应骨架屏呢?【Vue 3 自定义指令 — 骨架屏】结果还真给我想出来了! 用
指令
先看效果 o((>ω< ))o ~
文章图片
实现原理 我们 自定义2个指令,分别叫做
skeleton
、skeleton-item
// skeleton.ts
import { reactive, watchEffect, h, render } from 'vue'const state = reactive({
// 加载状态
loading: false,
// 使用了 v-skeleton-item 指令的节点保存在这里
list: []
})watchEffect(() => {
// 创建 vnode
const children = state.list.map((el) =>
h('div', {
style: {
position: 'absolute',
top: el.getBoundingClientRect().top + 'px',
left: el.getBoundingClientRect().left + 'px',
width: el.getBoundingClientRect().width + 'px',
height: el.getBoundingClientRect().height + 'px',
background: '#e5e5e5',
borderRadius: getComputedStyle(el).borderRadius,
},
})
);
// 创建 div 容器
const container = h('div', children)// 将 div容器 渲染到 body 中
render(state.loading ? container : null, document.body)
})const Skeleton = {
mounted(el, binding) {
state.loading = binding.value
},
updated(el, binding) {
state.loading = binding.value
},
unmounted(el) {
state.loading = false
}
}const SkeletonItem = {
mounted(el, binding) {
// 保存 el
state.list.push(el)
},
unmounted(el) {
// 删除 el
const i = state.list.indexOf(el)
if (i == -1) return
state.list.splice(i, 1)
}
}// 注册这2个指令
export default {
install: app => {
app.directive('skeleton', Skeleton)
app.directive('skeleton-item', SkeletonItem)
}
}export { Skeleton, SkeletonItem }
点击(在线运行)示例代码
实现原理其实很简单
- 我们先自定义2个指令,分别叫做
skeleton
: 用于控制loading
状态skeleton-item
: 用于标记需要创建骨骼的节点 - 在
SkeletonItem
的mounted
钩子函数将el
保存到list
里面 - 遍历
list
创建对应的vnode
,
并且调用el.getBoundingClientRect()
获取el
的位置大小设置给vnode
,
使vnode
和el
正好重叠在一个位置 - 最后调用
render(state.loading ? container : null, document.body)
把骨架屏
渲染出来。(state.loading
是由skeleton
指令控制的)
npm i -S @x-ui-vue3/skeleton
main.js
import { createApp } from 'vue'
import Skeleton from '@x-ui-vue3/skeleton'
import App from './App.vue'createApp(App).use(Skeleton).mount('#app')
App.vue
超文本标记语言是一种用于创建网页的标准标记语言。
www.runoob.com
Good good study, day day up!
文章图片
更多示例
文章图片
文章图片
- DEMO 1
- DEMO 2
- DEMO 3
你的点赞?对我非常重要,也是我坚持的动力
推荐阅读
- 关于swiper插件在vue2的使用
- S1.|Vue组件------star组件设计
- React自定义hook之(useClickOutside——判断是否点击DOM之外区域)
- Vue|Vue 安装 vue的基本使用 vue的初步使用步骤
- Vue2自定义插件的写法-Vue.use()
- create-react-app常用自定义配置教程示例
- vue中radio根据动态值绑定checked无效的解决
- Vue3|Vue3 10多种组件通讯方法
- Vue.js项目在apache服务器部署问题解决
- node.js中的模块化标准CommonJS与自定义模块