美文网首页
VUE编写UI组件

VUE编写UI组件

作者: 懒先森 | 来源:发表于2016-05-30 12:11 被阅读1815次
    写组件从来就不是一件难事,如果非要说有什么实现障碍,懒算吗???
    

    这是大致总结的一种组件编写思路 整个编写的过程也是按照这个流程来做的。


    Paste_Image.png

    需求

    不管需求是来自于老板、产品亦或是设计师,总之他能讲出道理或者他能拍板,干就是了
    
    设计图
    Paste_Image.png
    交互说明

    正常这个需要设计师或者产品(以下均简称设计)做出交互demo
    因为有时候设计不亲自做交互效果的话 他不容易想到一些交互细节,比如

    • 小图在左右滑动后是否要贴边
    • 滑动速度怎么样

    在做一些其他丰富的ui组件时 要考虑的细节会更多 如果有时间 并且又能做作出交互demo的话 能更早的确定细节 确定这个组件的需求边界 工程师能更清楚的提前构思组件💭

    Paste_Image.png

    实现

    分拆
    写组件就像是造人,捡来树枝作出骨骼,拾起泥料作出皮肤,最后再给上一口的仙气
    
    1⃣骨骼

    说实话这是上周的某一天写的 然而现在让我回头看 已经不知道这画的标的是什么意思了


    结构过程

    大体结构就是


    Paste_Image.png
    我的习惯组件挂载点为一个容器结构(div) 里面再套一个组件实际的容器
    对了要有一个图片查看的遮罩层 别忘了 同组件容器并列
    2⃣长相很重要
    不管你承认不承认 颜值的重要程度远超一般的辩论论题
    

    开始给你的小人化妆了 用css让每个小块都排好 如果是更复杂的组件 那么要在样式上花费一段时间了 好在这个很简单……
    这里主要用到了flex布局和overhidden 没了……没啥可说的……

    3⃣这口仙气
    你戳死人一下 他不会说 也不会动 你戳活人一下 他会骂你娘
    

    正是有了交互才让组件有了灵气 变得好玩,使用事件来帮它搭上反射弧,接上神经
    来分析下这个组件的交互状态

    • 整个组件挂载容器上静止的
    • 包裹小图的容器要能够滑动 左滑 右滑
    • 每个小图要能够响应点击 打开遮罩层并显示大图
    • 大图要响应点击 关闭自身
    技术选型
    技术哪有对错 组合都是哲学
    

    咱们这里就是vue来做,能利用什么资源呢

    • 单文件 .vue带来的编写组件的便利 模版 样式 交互 都可以写在属于这个组件的地盘
    • vue-touch 基于hammerjs的移动端touch组件 可以很方便的实现左滑右滑 还有 tap
    • watch 监控属性 可以很方便的对数据状态的改变作出相应动作

    还有相当一部分童鞋不仔细看文档 文档真的是很重要


    vue如何编写可复用组件

    有了这些就足够了

    代码清单
    <template>
        <!--swiper 容器 满宽-->
        <div class="picswiper-container">
            <div v-touch:swipeleft="onSwipeLeft" v-touch:swiperight="onSwipeRight" class="picswiper-wrapper" v-bind:style="transitionObj">
                <div v-touch:tap="lookPic(pic)" class="picswiper-item" v-for="pic in piclist">
                    [站外图片上传中……(2)]
                </div>
            </div>
        </div>
        <div v-touch:tap="closeMark()" class="picviewer-mark" v-show="isLookPic">
            [站外图片上传中……(3)]
        </div>
    </template>
    <script>
        export default{
            props:["piclist","picflag"],
            data(){
                return{
                    transitionObj:{
                        'transition-duration':"1000ms",
                        'transform':"translate3d(0, 0, 0)"
                    },
                    $translateX:10,//阿里适配方案
                    swipeLeftCount:0,//滑动次数
                    $shouldSwipeCount:1,//滑了几次 默认为1
                    $picWidth:3,//每个小图的宽 rem
                    $picWrapperWidth:0,//组件容器的宽rem
                    isLookPic:false,//是否查看大图
                    curPic:""
                }
            },
            methods:{
                onSwipeLeft(eventObj){
                    let me = this;
                    //计算有几个图片块
                    if(me.swipeLeftCount!=me.$data.$shouldSwipeCount){
                        me.swipeLeftCount++
                    }
                },
                onSwipeRight(){
                    let me = this;
                    //计算有几个图片块
                    if(me.swipeLeftCount!=0){
                        --me.swipeLeftCount
                    }
                },
                lookPic(pic){
                    this.curPic = pic
                    this.isLookPic = true
                },
                closeMark(){
                    this.isLookPic = false
                }
            },
            watch:{
                /**
                 * 监控数据
                 * 根据当前第几次 来判断滑动方向
                 * 在piclist存在时 进行一些配置数据的初始化
                 * @param val
                 * @param oldVal
                 */
                swipeLeftCount(val,oldVal){
                    let me = this;
                    if(val>oldVal){//往左滑
                        me.transitionObj.transform="translate3d(-"+me.$data.$translateX*val+"rem, 0, 0)"
                    }else if(val<oldVal){//向右滑
                        if(me.$data.$translateX/val=="Infinity"){//到头了
                            me.transitionObj.transform="translate3d(0, 0, 0)"
                        }else{
                            me.transitionObj.transform="translate3d(-"+me.$data.$translateX/val+"rem, 0, 0)"
                        }
                    }
                },
                /**
                 * 监控数据
                 * 在piclist存在时 进行一些配置数据的初始化
                 * @param val
                 * @param oldVal
                 */
                piclist(val,oldVal){
                    let me = this;
                    if(!!val){
                        me.$data.$picWrapperWidth = val.length*me.$data.$picWidth;
                        me.$data.$shouldSwipeCount = Math.floor(me.$data.$picWrapperWidth/me.$data.$translateX)
                    }
    
                }
            }
        }
    </script>
    <style scope>
    .picswiper-container {
        width:100%;
        height:2.666666667rem;
        overflow: hidden;
    }
    .picswiper-wrapper {
        position: relative;
        width: 100%;
        height: 100%;
        z-index: 1;
        display: -webkit-box;
        display: -webkit-flex;
        display: flex;
        -webkit-transition-property: -webkit-transform;
        -ms-transition-property: -ms-transform;
        transition-property: transform;
        -webkit-box-sizing: content-box;
        box-sizing: content-box;
    }
    .picswiper-item {
        width:2.666666667rem;
        height:auto;
        -webkit-flex-shrink: 0;
        -ms-flex: 0 0 auto;
        flex-shrink: 0;
        position: relative;
        text-align: center;
        font-size: 18px;
        background: #fff;
        display: -webkit-box;
        display: -webkit-flex;
        display: flex;
        -webkit-box-pack: center;
        -webkit-justify-content: center;
        justify-content: center;
        -webkit-box-align: center;
        -webkit-align-items: center;
        align-items: center;
        margin-right: 0.2rem;
        overflow: hidden;
    }
    .picviewer-mark {
        position: fixed;
         top: 0; 
        bottom: 0;
        left: 0;
        height: 100%;
        width: 100%;
        z-index: 20009;
        background: rgba(0,0,0,0.8);
        padding-top: 50%;
        text-align: center;
    }
    </style>
    

    怎么算完了?

    • 完备测试
    • 代码规范优化 包括书写优化 复用优化
    • 性能有没有优化的
    • 文档补充等等等
      对这个组件来说,可优化的点太多了 包括配置项对外暴露 适配方案的兼容 图片数量测试等等,只是想借这个例子记录下写组件的思路

    结语

    写代码往往很快 思考怎么写往往费力 但也最为好玩
    enjoy in think no matter what you do 
    

    相关文章

      网友评论

          本文标题:VUE编写UI组件

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