需求分析:
如图, 有很多高度不固定的模块 (图中只显示两个, 本人项目有十三个), 点击模块标题展开相应的模块, 再次点击此模块匿藏, 如何实现此需求并实现复用?
点击红框前:
点击后:
难点分析:
模块高度不固定. 比如, 本人一开始找到的方法如下:
- <!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 实现垂直展开, 收缩不定高度模块组件实现完成及应用均已完成.
实现效果:
来源: https://blog.csdn.net/fabulous1111/article/details/79978545