美文网首页Vue.jsVue
vue-cli3 配置骨架屏方案

vue-cli3 配置骨架屏方案

作者: w候人兮猗 | 来源:发表于2019-03-01 23:23 被阅读0次

    vue-cli3配置骨架屏方案

    前言

    最近在学vue,准备使用vue写一个移动端项目。考虑到首页白屏优化,需要实现骨架屏需求。

    步骤

    • 安装vue-skeleton-webpack-plugin插件
    npm install --save-dev vue-skeleton-webpack-plugin
    
    • vue.config.js配置
    const path = require('path')
    const SkeletonWebpackPlugin = require('vue-skeleton-webpack-plugin');
    
    module.exports = {
        css: {
             extract: true, // css拆分ExtractTextPlugin插件,默认true - 骨架屏需要为true
        },
        
        configureWebpack: (config)=>{
            // vue骨架屏插件配置
            config.plugins.push(new SkeletonWebpackPlugin({
              webpackConfig: {
                entry: {
                  app: path.join(__dirname, './src/utils/skeleton.js'),
                },
              },
              minimize: true,
              quiet: true,
            }))
      },
    }
    
    • 新建一个skeleton.js文件放在src->utils文件夹下面、
    import Vue from 'vue';
    import Skeleton from '../components/Skeleton/skeleton-2';
    
    export default new Vue({
      components: {
        Skeleton,
      },
      render: h => h(Skeleton),
    });
    
    
    这个文件是用来注入骨架屏的
    
    • 新建一个skeleton-2.vue骨架屏组件
    <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>
    
    
    • 新建一个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>
    
    • 修改main.js配置
    const app = new Vue({
      store,
      router,
      render: h => h(App)
    }).$mount('#app')
    
    • 重启项目

    思路

    • 将骨架屏也看成路由组件,在构建时使用 Vue 预渲染功能,将骨架屏组件的渲染结果 HTML 片段插入 HTML 页面模版的挂载点中,将样式内联到 head 标签中。这样等前端渲染完成时,Vue 将使用客户端混合,把挂载点中的骨架屏内容替换成真正的页面内容。

    缺点

    • 这种方案实现的是固定死的骨架(可以查看skeleton-2.vue skeleton-1.vue)两个文件,不能够自动根据页面DOM结构生成骨架

    优化的方向

    参考

    相关文章

      网友评论

        本文标题:vue-cli3 配置骨架屏方案

        本文链接:https://www.haomeiwen.com/subject/zorsuqtx.html