vue-cli3.0 项目内使用vue-skeleton-webpack-plugin插件根据路由来渲染不同的骨架屏
为了前端体验更加友好,减缓用户的焦虑情绪,提升项目质量等,我们在项目里面可以使用骨架屏,提前渲染出来一个跟正式页面相似的页面出来,减小首屏加载时间。在vue中使用骨架屏因为我们的代码会使用webpack打包,所以在我们的js下载运行之前,用户是无法在页面上看到信息,所以,我们要把骨架屏相关的代码放到HTML里面,当然,可以把代码直接写在html文件的<div id=’app‘>...
为了前端体验更加友好,减缓用户的焦虑情绪,提升项目质量等,我们在项目里面可以使用骨架屏,提前渲染出来一个跟正式页面相似的页面出来,减小首屏加载时间。
在vue中使用骨架屏
因为我们的代码会使用webpack
打包,所以在我们的js
下载运行之前,用户是无法在页面上看到信息,所以,我们要把骨架屏相关的代码放到HTML
里面,当然,可以把代码直接写在html文件的<div id=’app‘></div>
里面,但是为了维护我们进行开发时的体验,我们在开发时可以使用一个webpack
插件,来像开发组件一样来开发骨架屏。
1.全局安装@vue/cli(Vue CLI 3的包名称由 vue-cli
改成了 @vue/cli
)
npm install -g @vue/cli
2.新建vue-skeleton项目
vue create vue-skeleton
3.添加vue-skeleton-webpack-plugin
插件
npm install vue-skeleton-webpack-plugin
4.创建骨架屏文件
在src文件夹下新建skeleton目录,并在这个目录内新建listSkeleton.vue、detailSkeleton.vue,两个文件内的内容如下:
<!--listSkeleton.vue -->
<template>
<div class="container">
<div>列表骨架屏</div>
<img
src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMTA4MCAyNjEiPjxkZWZzPjxwYXRoIGlkPSJiIiBkPSJNMCAwaDEwODB2MjYwSDB6Ii8+PGZpbHRlciBpZD0iYSIgd2lkdGg9IjIwMCUiIGhlaWdodD0iMjAwJSIgeD0iLTUwJSIgeT0iLTUwJSIgZmlsdGVyVW5pdHM9Im9iamVjdEJvdW5kaW5nQm94Ij48ZmVPZmZzZXQgZHk9Ii0xIiBpbj0iU291cmNlQWxwaGEiIHJlc3VsdD0ic2hhZG93T2Zmc2V0T3V0ZXIxIi8+PGZlQ29sb3JNYXRyaXggaW49InNoYWRvd09mZnNldE91dGVyMSIgdmFsdWVzPSIwIDAgMCAwIDAuOTMzMzMzMzMzIDAgMCAwIDAgMC45MzMzMzMzMzMgMCAwIDAgMCAwLjkzMzMzMzMzMyAwIDAgMCAxIDAiLz48L2ZpbHRlcj48L2RlZnM+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwIDEpIj48dXNlIGZpbGw9IiMwMDAiIGZpbHRlcj0idXJsKCNhKSIgeGxpbms6aHJlZj0iI2IiLz48dXNlIGZpbGw9IiNGRkYiIHhsaW5rOmhyZWY9IiNiIi8+PHBhdGggZmlsbD0iI0Y2RjZGNiIgZD0iTTIzMCA0NGg1MzN2NDZIMjMweiIvPjxyZWN0IHdpZHRoPSIxNzIiIGhlaWdodD0iMTcyIiB4PSIzMCIgeT0iNDQiIGZpbGw9IiNGNkY2RjYiIHJ4PSI0Ii8+PHBhdGggZmlsbD0iI0Y2RjZGNiIgZD0iTTIzMCAxMThoMzY5djMwSDIzMHpNMjMwIDE4MmgzMjN2MzBIMjMwek04MTIgMTE1aDIzOHYzOUg4MTJ6TTgwOCAxODRoMjQydjMwSDgwOHpNOTE3IDQ4aDEzM3YzN0g5MTd6Ii8+PC9nPjwvc3ZnPg=="
/>
<img
src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMTA4MCAyNjEiPjxkZWZzPjxwYXRoIGlkPSJiIiBkPSJNMCAwaDEwODB2MjYwSDB6Ii8+PGZpbHRlciBpZD0iYSIgd2lkdGg9IjIwMCUiIGhlaWdodD0iMjAwJSIgeD0iLTUwJSIgeT0iLTUwJSIgZmlsdGVyVW5pdHM9Im9iamVjdEJvdW5kaW5nQm94Ij48ZmVPZmZzZXQgZHk9Ii0xIiBpbj0iU291cmNlQWxwaGEiIHJlc3VsdD0ic2hhZG93T2Zmc2V0T3V0ZXIxIi8+PGZlQ29sb3JNYXRyaXggaW49InNoYWRvd09mZnNldE91dGVyMSIgdmFsdWVzPSIwIDAgMCAwIDAuOTMzMzMzMzMzIDAgMCAwIDAgMC45MzMzMzMzMzMgMCAwIDAgMCAwLjkzMzMzMzMzMyAwIDAgMCAxIDAiLz48L2ZpbHRlcj48L2RlZnM+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwIDEpIj48dXNlIGZpbGw9IiMwMDAiIGZpbHRlcj0idXJsKCNhKSIgeGxpbms6aHJlZj0iI2IiLz48dXNlIGZpbGw9IiNGRkYiIHhsaW5rOmhyZWY9IiNiIi8+PHBhdGggZmlsbD0iI0Y2RjZGNiIgZD0iTTIzMCA0NGg1MzN2NDZIMjMweiIvPjxyZWN0IHdpZHRoPSIxNzIiIGhlaWdodD0iMTcyIiB4PSIzMCIgeT0iNDQiIGZpbGw9IiNGNkY2RjYiIHJ4PSI0Ii8+PHBhdGggZmlsbD0iI0Y2RjZGNiIgZD0iTTIzMCAxMThoMzY5djMwSDIzMHpNMjMwIDE4MmgzMjN2MzBIMjMwek04MTIgMTE1aDIzOHYzOUg4MTJ6TTgwOCAxODRoMjQydjMwSDgwOHpNOTE3IDQ4aDEzM3YzN0g5MTd6Ii8+PC9nPjwvc3ZnPg=="
/>
</div>
</template>
<script>
export default {
components: {},
data () {
return {}
},
mounted () {},
methods: {}
}
</script>
<style scoped lang="scss">
</style>
<!-- detailSkeleton.vue -->
<template>
<div class="container">
详情骨架屏
<img
src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMTA4MCAyNjEiPjxkZWZzPjxwYXRoIGlkPSJiIiBkPSJNMCAwaDEwODB2MjYwSDB6Ii8+PGZpbHRlciBpZD0iYSIgd2lkdGg9IjIwMCUiIGhlaWdodD0iMjAwJSIgeD0iLTUwJSIgeT0iLTUwJSIgZmlsdGVyVW5pdHM9Im9iamVjdEJvdW5kaW5nQm94Ij48ZmVPZmZzZXQgZHk9Ii0xIiBpbj0iU291cmNlQWxwaGEiIHJlc3VsdD0ic2hhZG93T2Zmc2V0T3V0ZXIxIi8+PGZlQ29sb3JNYXRyaXggaW49InNoYWRvd09mZnNldE91dGVyMSIgdmFsdWVzPSIwIDAgMCAwIDAuOTMzMzMzMzMzIDAgMCAwIDAgMC45MzMzMzMzMzMgMCAwIDAgMCAwLjkzMzMzMzMzMyAwIDAgMCAxIDAiLz48L2ZpbHRlcj48L2RlZnM+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwIDEpIj48dXNlIGZpbGw9IiMwMDAiIGZpbHRlcj0idXJsKCNhKSIgeGxpbms6aHJlZj0iI2IiLz48dXNlIGZpbGw9IiNGRkYiIHhsaW5rOmhyZWY9IiNiIi8+PHBhdGggZmlsbD0iI0Y2RjZGNiIgZD0iTTIzMCA0NGg1MzN2NDZIMjMweiIvPjxyZWN0IHdpZHRoPSIxNzIiIGhlaWdodD0iMTcyIiB4PSIzMCIgeT0iNDQiIGZpbGw9IiNGNkY2RjYiIHJ4PSI0Ii8+PHBhdGggZmlsbD0iI0Y2RjZGNiIgZD0iTTIzMCAxMThoMzY5djMwSDIzMHpNMjMwIDE4MmgzMjN2MzBIMjMwek04MTIgMTE1aDIzOHYzOUg4MTJ6TTgwOCAxODRoMjQydjMwSDgwOHpNOTE3IDQ4aDEzM3YzN0g5MTd6Ii8+PC9nPjwvc3ZnPg=="
/>
</div>
</template>
<script>
export default {
components: {},
data () {
return {}
},
mounted () {},
methods: {}
}
</script>
<style scoped lang="scss">
</style>
在这个页面里面我们可以根据需要来编写代码,最好使用样式或者base64
的图片,以减少初始的请求。
5.新建一个Skeleton.js
入口文件
在main.js
同级新建一个Skeleton.js,内容如下:
// skeleton.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>
`
})
6.配置打包方案
在项目根目录新建vue.config.js
,在里面配置vue-skeleton-webpack-plugin
插件,并开启css
分离;
根据配置各个路由路径对应的 Skeleton
//vue.config.js
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: {
mode: 'hash',
routes: [
{ path: '/', skeletonId: 'listSkeleton' },
{ path: /^\/detail/, skeletonId: 'detailSkeleton' }
]
}
}))
},
// css相关配置
css: {
// 是否使用css分离插件 ExtractTextPlugin
extract: true,
// 开启 CSS source maps?
sourceMap: false,
// 启用 CSS modules for all css / pre-processor files.
modules: false
}
}
vue-skeleton-webpack-plugin
插件参数说明
- webpackConfig 必填,渲染 skeleton 的 webpack 配置对象
- insertAfter 选填,渲染 DOM 结果插入位置,默认值为字符串
'<div id="app">'
- 也可以传入
Function
,方法签名为insertAfter(entryKey: string): string
,返回值为挂载点字符串
- 也可以传入
- quiet 选填,在服务端渲染时是否需要输出信息到控制台
- router 选填 SPA 下配置各个路由路径对应的 Skeleton
- mode 选填 路由模式,两个有效值
history|hash
- routes 选填 路由数组,其中每个路由对象包含两个属性:
- path 路由路径
string|RegExp
- skeletonId Skeleton DOM 的 id
string
- path 路由路径
- mode 选填 路由模式,两个有效值
- minimize 选填 SPA 下是否需要压缩注入 HTML 的 JS 代码
7.在浏览器中查看效果
因为网络快的时候,我们是不显示骨架屏的,所以要把我们的浏览器网络调慢一点(调整为solw 3G),以方便我们开发和调试;
首页加载时:
detail页面加载时
我们会看到骨架屏先被渲染出来,然后才会有我们的页面渲染出来;
更多推荐
所有评论(0)