zoukankan      html  css  js  c++  java
  • vue手写骨架屏插件

    我们在h5开发的过程中,内容可能是根据后台返回数据动态渲染出来的,但是,这样会造成跳屏,体验不好,一些应用中采用了骨架屏的设计,例如今日头条。在没有数据的时候使用骨架屏占位,今天咱们写一个vue骨架屏的插件。

    写插件要采用api倒推的思想,想要用户怎么引入,怎么调用,根据用户的使用倒推写法。

    首先我们引入一些vue插件的时候先引入样式,然后import引入一个js文件,最后vue.use(刚才引入的文件)

    我们给骨架屏插件起个名字叫 skeleton ,我们希望用户将来是这么使用的

    import './components/skeleton/skeleton.css'
    import skeleton from './components/skeleton/skeleton'
    Vue.use(skeleton)

    希望将来用户用如下方式引入组件:

    <skeleton :type="[{style:'list1',times:5},{style:'list2',times:4}]" v-if="isShow"></skeleton>

    type是个对象数组,style代表插件提供的风格,times代表循环几次,我们的设计目标是可以在同一屏实现多个风格的骨架屏

    那么首先我们要实现skeleton.js ,这个js有如下几个功能:

    1 返回一个对象

    2 作为vue插件,返回的对象要包含install方法

    3 要创建一个全局组件,将来调用的时候不需要再进行引入

    代码如下

    class skeleton{
        constructor(v){
            this.vm = v;
        }
        
        install(vm){    //将来Vue.use会调用install方法,将vue实例作为参数传入。
            // vm:vue实例对象
            console.log("this is skeleton plugin")
            vm.component('skeleton',this.skeExtend(vm))  //注册一个全局组件,名字叫skeleton ,第二个参数是使用vue.extend创建的子类
        }
        skeExtend(v){
            return v.extend({
                template:
                `<div class="ske-con">
                    <div v-for="item,index in computedType" :key="index" class="ske-style-1">
                        <div v-for="it,index in item.times" :key="index" class="ske-single-cell">
                            <div class="ske-item">
                                <div class="ske-list-title"></div>
                                <div class="ske-list-con"></div>
                            </div>
                        </div>
                    </div>
                    <div v-for="item,index in computedType2" :key="item.style" class="ske-style-2">
                        <div v-for="it,index in item.times" :key="index" class="ske-single-cell">
                            <div class="ske-item">
                                <div class="left-part">
                                    <div class="content1"></div>
                                    <div class="content2"></div>
                                </div>
                                <div class="right-part">
    
                                </div>
    
                            </div>
                        </div>
                    </div>
                </div>`,
                props:{
                    type:{
                        type:[String,Array],
                        desc:"骨架屏选项,传入结构为[{style:'list1',times:3},{style:'list2',times:4}]的数据,传入风格和循环的数量",
                        required:true
                    }
                },
                computed:{
                    computedType(){
                        let newArr = []
                        this.type.forEach(item=>{
                            if(item.style=='list1'){
                                newArr.push(item)
                            }
                            
                        })
                        return newArr;
                    },
                    computedType2(){
                        let newArr = []
                        this.type.forEach(item=>{
                            if(item.style=='list2'){
                                newArr.push(item)
                            }
                            
                        })
                        return newArr;
                    }
                },
    
            })
        }
    }
    let s = new skeleton()
    
    export default s;

    样式如下

    /*  */
    .ske-class-list-1{
        
    }
    /*  */
    .ske-class-list-2{
        
    }
    
    /* common */
    .ske-con{
        background:#fff;
    }
    .ske-single-cell{
        100vw;
    }
    .ske-style-1 .ske-item{
        95%;
        margin:0 auto;
        display:flex;
        height:40px;
        border-bottom:1px solid #e4e4e4;
    }
    .ske-style-1 .ske-list-title{
        30%;
        background:#e4e4e4;
        height:30px;
        margin-top:5px;
    }
    .ske-style-1 .ske-list-con{
        flex:1;
        background:#e4e4e4;
        margin-left:50px;
        height:30px;
        margin-top:5px;
    }
    /* .ske-style-2  */
    
    .ske-style-2  .ske-item{
        height:60px;
        95%;
        margin:0 auto;
        display:flex;
        box-sizing: border-box;
        padding-top:10px;
        padding-bottom:10px;
    }
    .ske-style-2 .left-part{
        float:left;
        70%;
        
    }
    .ske-style-2 .left-part .content1{
        background:#e4e4e4;
        height:20px;
        100%;
    }
    .ske-style-2 .left-part .content2{
        background:#e4e4e4;
        height:20px;
        80%;
        margin-top:5px;
    }
    .ske-style-2 .right-part{
        background:#e4e4e4;
        flex:1;
        margin-left:20px;
    }

    如果公司有自己的定制化骨架屏尺寸,可以根据ui要求去增加一些样式。

  • 相关阅读:
    unix中的rm,rmdir的使用
    jQuery的学习笔记4
    jQuery的学习笔记2
    outlook 2016 for windows 每次刷新发送接收邮件会弹出登陆界面
    Azure SQL Data Warehouse
    Hadoop---Google MapReduce(转)
    Java 1.8特性
    SQL——Mysql数据库介绍
    接口和简单工厂设计模式
    自定义异常
  • 原文地址:https://www.cnblogs.com/panda-programmer/p/13386216.html
Copyright © 2011-2022 走看看