前言
前人栽树后人乘凉, 骨架屏到现在已经非常多的解决方案, 用之即可 ...
方式
安装插件
vue.config.JS 配置
- const path = require('path')
- const SkeletonWebpackPlugin = require('vue-skeleton-webpack-plugin');
- module.exports = {
- CSS: {
- // CSS 拆分 ExtractTextPlugin 插件, 默认 true - 骨架屏需要为 true
- extract: true,
- },
- configureWebpack: (config)=>{
- // vue 骨架屏插件配置
- config.plugins.push(new SkeletonWebpackPlugin({
- webpackConfig: {
- entry: {
- App: path.join(__dirname, './src/config/skeleton.js'),
- },
- },
- minimize: true,
- quiet: true,
- }))
- },
- }
新增一个骨架屏注入 JS 文件, 这里命名为 skeleton.JS, 放置在 config 文件夹下
- import Vue from 'vue';
- import Skeleton from '../static/skeleton/skeleton-2';
- export default new Vue({
- components: {
- Skeleton,
- },
- render: h => h(Skeleton),
- });
骨架屏的 vue 文件, skeleton-2.vue 文件, 文件引用, 感谢作者分享 https://segmentfault.com/a/1190000014832185
- <template>
- <div class="skeleton page">
- <div class="skeleton-nav"></div>
- <div class="skeleton-swiper"></div>
- <ul class="skeleton-tabs">
- <li v-for="i in 8" class="skeleton-tabs-item"><span></span></li>
- </ul>
- <div class="skeleton-banner"></div>
- <div v-for="i in 6" class="skeleton-productions"></div>
- </div>
- </template>
- <style>
- .skeleton {
- position: relative;
- height: 100%;
- overflow: hidden;
- padding: 15px;
- box-sizing: border-box;
- background: #fff;
- }
- .skeleton-nav {
- height: 45px;
- background: #eee;
- margin-bottom: 15px;
- }
- .skeleton-swiper {
- height: 160px;
- background: #eee;
- margin-bottom: 15px;
- }
- .skeleton-tabs {
- list-style: none;
- padding: 0;
- margin: 0 -15px;
- display: flex;
- flex-wrap: wrap;
- }
- .skeleton-tabs-item {
- width: 25%;
- height: 55px;
- box-sizing: border-box;
- text-align: center;
- margin-bottom: 15px;
- }
- .skeleton-tabs-item span {
- display: inline-block;
- width: 55px;
- height: 55px;
- border-radius: 55px;
- background: #eee;
- }
- .skeleton-banner {
- height: 60px;
- background: #eee;
- margin-bottom: 15px;
- }
- .skeleton-productions {
- height: 20px;
- margin-bottom: 15px;
- background: #eee;
- }
- .skeleton {
- padding: 10px;
- }
- .skeleton .skeleton-head,
- .skeleton .skeleton-title,
- .skeleton .skeleton-content {
- background: rgb(194, 207, 214);
- }
- .skeleton-head {
- width: 100px;
- height: 100px;
- float: left;
- }
- .skeleton-body {
- margin-left: 110px;
- }
- .skeleton-title {
- width: 500px;
- height: 60px;
- transform-origin: left;
- animation: skeleton-stretch .5s linear infinite alternate;
- }
- .skeleton-content {
- width: 260px;
- height: 30px;
- margin-top: 10px;
- transform-origin: left;
- animation: skeleton-stretch .5s -.3s linear infinite alternate;
- }
- @keyframes skeleton-stretch {
- from {
- transform: scalex(1);
- }
- to {
- transform: scalex(.3);
- }
- }
- </style>
骨架屏的 vue 文件, skeleton-1.vue 文件, 文件引用, 感谢另一位作者分享
- <template>
- <div class="skeleton">
- <div class="skeleton-head"></div>
- <div class="skeleton-body">
- <div class="skeleton-title"></div>
- <div class="skeleton-content"></div>
- </div>
- </div>
- </template>
- <style>
- .skeleton {
- padding: 10px;
- }
- .skeleton .skeleton-head,
- .skeleton .skeleton-title,
- .skeleton .skeleton-content {
- background: rgb(194, 207, 214);
- }
- .skeleton-head {
- width: 100px;
- height: 100px;
- float: left;
- }
- .skeleton-body {
- margin-left: 110px;
- }
- .skeleton-title {
- width: 500px;
- height: 60px;
- transform-origin: left;
- animation: skeleton-stretch 0.5s linear infinite alternate;
- }
- .skeleton-content {
- width: 260px;
- height: 30px;
- margin-top: 10px;
- transform-origin: left;
- animation: skeleton-stretch 0.5s -0.3s linear infinite alternate;
- }
- @keyframes skeleton-stretch {
- from {
- transform: scalex(1);
- }
- to {
- transform: scalex(0.3);
- }
- }
- </style>
为了加载效果更佳, 避免浏览器加载 CSS 阻塞, 在 main.JS 新增如下配置
- const App = new Vue({
- store,
- router,
- render: h => h(App)
- })
- // 如果 JS 晚于 CSS 加载完成, 那直接执行渲染
- if (process.env.NODE_ENV === 'production') {
- if (Windows.STYLE_READY) {
- App.$mount('#app')
- }
- } else {
- App.$mount('#app')
- }
备注
到此骨架屏就完成了, 这仅仅是固定样式的骨架屏, 有时间再研究运行时渲染方案
malk 2018-12-6
来源: http://www.jianshu.com/p/0e5ea7228fb7