Vue项目添加骨架屏

    科技2023-09-21  95

    Vue 骨架屏的使用

    为什么使用骨架屏骨架屏的实现原理实现一个简单的骨架屏如何使用骨架屏插件来项目添加骨架屏

    什么是骨架屏

    由于页面在加载时需要加载许多资源文件和数据,导致页面在显示时有一段时间的白屏或闪烁,所以伪类解决这一问题就出现了骨架屏这一方案。简单来说,骨架屏就是在页面内容未加载完成的时候,先使用一些图形进行占位,待内容加载完成之后再把它替换掉。

    骨架屏实现原理

    实现一个简单的骨架屏

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link rel="icon" href="<%= BASE_URL %>favicon.ico"> <title><%= htmlWebpackPlugin.options.title %></title> <style rel="stylesheet" type="text/css"> .skeleton { background: red; display: none; } </style> </head> <body> <noscript> <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> </noscript> <div id="app"> <p class="skeleton" data-index="/">我是首页骨架屏内容</p> <p class="skeleton" data-index="/test">我是测试页骨架屏内容</p> <p class="skeleton">我是默认的骨架屏</p> </div> <script> let pathname = window.location.pathname let domList = document.getElementsByClassName('skeleton') let len = domList.length let indexList = [] for(let i = 0; i < len; i++) { let dom = domList[i] indexList.push(dom.dataset.index) } let index = indexList.indexOf(pathname) if(index > -1) { domList[index].style.display='block' }else { domList[len-1].style.display='block' } </script> <!-- built files will be auto injected --> </body> </html>

    将 Vue 的模板页替换成这样,就实现了一个简单的骨架屏。当然在实际使用时这样是不够的。

    使用骨架

    使用 vue-skeleton-webpack-plugin 插件,当然也可以自己造轮子。

    创建骨架屏组件(和创建普通的组件一样创建就行)创建 skeleton.js 文件 ,这个文件主要是在 main.js 文件中引入的在 webpack (vue.config.js)中配置 vue-skeleton-webpack-plucin 插件

    skeleton.js 文件

    // skeleton.js 此文件必须在 main.js (项目入口文件)中引入 import Vue from 'vue' import listSkeleton from './skeleton/listSkeleton' import detailSkeleton from './skeleton/detailSkeleton' export default new Vue({ components: { listSkeleton, detailSkeleton }, template: ` <div> <listSkeleton id="listSkeleton" style="display:none;" /> <detailSkeleton id="detailSkeleton" style="display:none;" /> </div> ` // 如果项目通用一个骨架屏,这里就不需要 template 了,可以使用 render: h => h(Skeleton) 即可 })

    vue-skeleton-webpack-plugin 插件参数说明

    webpackConfig 必填,渲染 skeleton 的 webpack 配置对象insertAfter 选填,渲染 DOM 结果插入位置,默认值为字符串 <div id="app"> 也可以传入 Function,方法签名为 insertAfter(entryKey: string): string,返回值为挂载点字符串 quiet 选填,在服务端渲染时是否需要输出信息到控制台router 选填,SPA 下配置各个路由路径对应的 Skeleton mode 选填 路由模式,两个有效值 history|hashroutes 选填, 路由数组,其中每个路由对象包含两个属性: path ,路由路径 string|RegExpskeletonId ,Skeleton DOM的 id string minimize 选填, SPA 下是否需要压缩注入 HTML 的 javascript 代码 // vue.config.js 不一定限制在此文件中设置,只要在 webpack 配置插件的地方引入即可 const path = require('path'); const SkeletonWebpackPlugin = require('vue-skeleton-webpack-plugin'); module.exports = { configureWebpack: (config)=>{ config.plugins.push(new SkeletonWebpackPlugin({ webpackConfig: { entry: { app: path.join(__dirname, './src/skeleton.js'), }, }, minimize: true, quiet: true, // 如果页面通用一个骨架屏,那么就不需要设置router字段了 router: { mode: 'hash', routes: [ { path: '/', skeletonId: 'listSkeleton' }, { path: /^\/detail/, skeletonId: 'detailSkeleton' } ] } } }, css: { // 使用 css 分离插件 mini-css-extract-plugin,不然骨架屏组件里的 <style> 不起作用, extract: true, } };
    Processed: 0.019, SQL: 8