Vue.JS实现垂直方向展开、收缩不定高度模块的JS组件

需求分析:

如图,有很多高度不固定的模块(图中只显示两个,本人项目有十三个),点击模块标题展开相应的模块,再次点击此模块匿藏,如何实现此需求并实现复用?
点击红框前:
这里写图片描述
点击后:
这里写图片描述

难点分析:

模块高度不固定。比如,本人一开始找到的方法如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .box{
            height:500px;
            background-color:black;  
             overflow: hidden;                       
        }
        .mybox-leave-active,.mybox-enter-active{
            transition:  all 1s ease; 
        }
        .mybox-leave-active,.mybox-enter{
            height:0px !important;
        }
        .mybox-leave,.mybox-enter-active{
            height: 500px;
        }
    </style>
</head>
<body>
<div id="box">
    <transition name="mybox">
        <div class="box"  v-show="boxshow"></div>
    </transition>
    <button @click="togglebox">按钮</button>
</div>
</body>
<script src="../bower_components/vue/dist/vue.js"></script>
<script>
    new Vue({
        el:'#box',
        data:{
            boxshow:false
        },
        methods:{

            togglebox:function(){
                this.boxshow = !this.boxshow;
            }
        }      
    });
</script>
</html>

这种方法确实可以实现点击展开,再次点击收缩的需求,但是有一个明显的缺点:限定了容器的高度,也就是每个模块都需要固定高度。

解决方案:

1、实现一个函数式组件

本人命名为vertical-toggle.js

// Created by xiaoqiang on 17/04/2018.
const elTransition = '0.3s height ease-in-out, 0.3s padding-top ease-in-out, 0.3s padding-bottom ease-in-out'
const Transition = {
  'before-enter' (el) {
    el.style.transition = elTransition
    if (!el.dataset) el.dataset = {}

    el.dataset.oldPaddingTop = el.style.paddingTop
    el.dataset.oldPaddingBottom = el.style.paddingBottom

    el.style.height = 0
    el.style.paddingTop = 0
    el.style.paddingBottom = 0
  },

  'enter' (el) {
    el.dataset.oldOverflow = el.style.overflow
    if (el.scrollHeight !== 0) {
      el.style.height = el.scrollHeight + 'px'
      el.style.paddingTop = el.dataset.oldPaddingTop
      el.style.paddingBottom = el.dataset.oldPaddingBottom
    } else {
      el.style.height = ''
      el.style.paddingTop = el.dataset.oldPaddingTop
      el.style.paddingBottom = el.dataset.oldPaddingBottom
    }

    el.style.overflow = 'hidden'
  },

  'after-enter' (el) {
    el.style.transition = ''
    el.style.height = ''
    el.style.overflow = el.dataset.oldOverflow
  },

  'before-leave' (el) {
    if (!el.dataset) el.dataset = {}
    el.dataset.oldPaddingTop = el.style.paddingTop
    el.dataset.oldPaddingBottom = el.style.paddingBottom
    el.dataset.oldOverflow = el.style.overflow

    el.style.height = el.scrollHeight + 'px'
    el.style.overflow = 'hidden'
  },

  'leave' (el) {
    if (el.scrollHeight !== 0) {
      el.style.transition = elTransition
      el.style.height = 0
      el.style.paddingTop = 0
      el.style.paddingBottom = 0
    }
  },

  'after-leave' (el) {
    el.style.transition = ''
    el.style.height = ''
    el.style.overflow = el.dataset.oldOverflow
    el.style.paddingTop = el.dataset.oldPaddingTop
    el.style.paddingBottom = el.dataset.oldPaddingBottom
  }
}

export default {
  name: 'VerticalToggle',
  functional: true,
  render (h, { children }) {
    const data = {
      on: Transition
    }
    return h('transition', data, children)
  }
}
2、引用此组件

这里写图片描述
components中注册了此组件:
这里写图片描述

即可在teamplate中引用,请留意红框文字说明部分。
这里写图片描述
至此,Vue.js实现垂直展开、收缩不定高度模块组件实现完成及应用均已完成。
实现效果:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/fabulous1111/article/details/79978545
今日推荐