zoukankan      html  css  js  c++  java
  • 一个step组件

    问题描述

    开发一个step组件,发现当页面放缩后step的步骤之间间隙变大,不能自动伸缩,于是想到监听元素宽度变化,重新设置step的宽度。

    解决方法

    1. 使用element-resize-detector
    // 首先安装 `element-resize-detector`
    
    // 引入
    const Detector = require('element-resize-detector')
    
    // 使用
    mounted () {
       this.handleStep()
    },
    methods: {
       // 监听step元素宽度变化
       handleStep() {
          let vm = this
          let detector = Detector()
          detector.listenTo(document.querySelector('.j-steps'), el => {
             vm.$nextTick(() => {
                vm.stepWidth = el.offsetWidth / this.curSteps.length + 'px'
               })
           })
        },
    }
    
    • 衍生问题--无法触发以下css发生变化
    li:not(:first-child) {}
    li:first-child {
        border-top-left-radius: 4px;
        border-bottom-left-radius: 4px;
        .left-arrow {
            display: none;
        }
    }
    li:last-child {
        border-top-right-radius: 4px;
        border-bottom-right-radius: 4px;
        .right-arrow {
            display: none;
        }
    }
    
    1. 使用指令监听
    directives:{
          resize: { // 指令的名称
            bind(el, binding) { // el为绑定的元素,binding为绑定给指令的对象
              console.log(el,"绑定",binding);
              let width = '', height = '';
              function isReize() {
                const style = document.defaultView.getComputedStyle(el);
                if (width !== style.width || height !== style.height) {
                  binding.value({style.width,height:style.height});  // 关键(这传入的是函数,所以执行此函数)
                }
                width = style.width;
                height = style.height;
              }
              el.__vueSetInterval__ = setInterval(isReize, 300);
            },
            unbind(el) {
              console.log(el,"解绑");
              clearInterval(el.__vueSetInterval__);
            }
          }
        },
    
    <div id="Chart1" v-resize="domResize"></div>
    
    domResize(data){
            let {width, height} = data; // 这里返回的宽高都是带单位的
            console.log("",width,"height:",height,"   dom尺寸方式改变");
          },
    
    • 这个方法是可行的。

    最终解决方法

    最终发现使用flex布局后,如果盒子内部的元素宽度足够大且相等,就能实现实时等分布局,于是直接设置每一个盒子内的 元素长度为1000px解决了[ganga]。

    step组件

    <template>
       <ul class="j-steps" ref="stepRef">
        <li class="step"
            :class="[index <= curVal?'isActive':'']"
            :style="{ '1000px'}"
            v-for="(item, index) in curSteps"
            :key="item">
          <div class="right-arrow"></div>
          <div class="left-arrow"></div>
          <span class="cur-step" v-html="index<curVal?'✓':index+1"></span>
          <span class="step-info">{{ item }}</span>
        </li>
       </ul>
    </template>
    <script>
    export default {
        name: 'Step',
        props: {
            value: {
                type: [String, Number],
                default: ''
            },
            steps: {
                type: Array,
                default: () => {
                    return []
                }
            }
        },
        watch: {
            value(val) {
                this.curVal = val
            },
            steps(val) {
                this.curSteps = val
            }
        },
        data() {
            return {
                curVal: this.value,
                curSteps: this.steps,
                stepWidth: 0
            }
        }
    }
    </script>
    <style lang="scss">
        @mixin j-step-arrow {
            content: '';
             0;
            height: 0;
            border-top: 24px solid transparent;
            border-bottom: 24px solid transparent;
            position: absolute;
            top: -1px;
        }
    
        .j-steps{
            display: flex;
            flex-wrap: nowrap;
            justify-content: space-between;
            li:not(:first-child) {
                margin-left:8px
            }
            li.step {
                position: relative;
                 238px;
                height: 48px;
                background: #F7F8FA;
                line-height: 48px;
                text-align: center;
            }
    
            .right-arrow:after {
                @include j-step-arrow;
                border-left: 12px solid #F7F8FA;
                right: -13px;
                z-index: 9;
            }
    
            .right-arrow:before {
                @include j-step-arrow;
                border-left: 12px solid #F7F8FA;
                right: -12px;
                z-index: 10;
            }
            .left-arrow:after{
                @include j-step-arrow;
                border-left: 12px solid #fff;
                left: -1px;
                z-index: 7;
            }
            .left-arrow:before{
                @include j-step-arrow;
                border-left: 12px solid #fff;
                left: -2px;
                z-index: 8;
            }
            li:first-child {
                border-top-left-radius: 4px;
                border-bottom-left-radius: 4px;
                .left-arrow {
                    display: none;
                }
            }
            li:last-child {
                border-top-right-radius: 4px;
                border-bottom-right-radius: 4px;
                .right-arrow {
                    display: none;
                }
            }
    
            .cur-step {
                display: inline-block;
                 18px;
                height: 18px;
                background: #C1C1C1;
                border-radius: 9px;
                color: #fff;
                line-height: 18px;
                text-align: center;
                margin: 0 6px 0 0;
            }
    
            .isActive {
                border: 1px solid #4260DB;
                .cur-step {
                    background: #4260DB;
                }
                .step-info{
                    color: #4260DB;
                    font-weight: 600;
                }
                .left-arrow:after,
                .right-arrow:after {
                    border-left: 12px solid #4260DB;
                }
            }
        }
    </style>
    
    <Step :steps="steps" v-model="curStep"></Step>
    
    data() {
       return {
          curStep: 0,
          steps: ['step1', 'step2'],
       };
    }
    
    handleNext() {
        let len = this.steps.length - 1
        if(++this.curStep > len) this.curStep = 0
    },
    
  • 相关阅读:
    jQuery 事件注册
    jQuery 获取元素当前位置offset()与position()
    jquery scrollTop()与scrollLeft()
    linux常用命令
    php5.6+apache2.4环境配置
    php 开启socket配置
    Node.js的学习路线
    apache配置rewrite及.htaccess文件(转载)
    php 获取域名等Url
    html5的本地存储
  • 原文地址:https://www.cnblogs.com/codebook/p/14310346.html
Copyright © 2011-2022 走看看