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要求去增加一些样式。

  • 相关阅读:
    Serialization and deserialization are bottlenecks in parallel and distributed computing, especially in machine learning applications with large objects and large quantities of data.
    Introduction to the Standard Directory Layout
    import 原理 及 导入 自定义、第三方 包
    403 'Forbidden'
    https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2
    These interactions can be expressed as complicated, large scale graphs. Mining data requires a distributed data processing engine
    mysqldump --flush-logs
    mysql dump 参数
    mysql dump 参数
    如果是在有master上开启了该参数,记得在slave端也要开启这个参数(salve需要stop后再重新start),否则在master上创建函数会导致replaction中断。
  • 原文地址:https://www.cnblogs.com/panda-programmer/p/13386216.html
Copyright © 2011-2022 走看看