当前位置:主页 > 网页前端 > vue >

vue.js实现简易折叠面板

时间:2022-11-07 09:38:14 | 栏目:vue | 点击:

本文实例为大家分享了vue.js实现简易折叠面板的具体代码,供大家参考,具体内容如下

代码如下:

主文件:app.vue

<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <collpase>
      <collpase-item
        :title="item.name"
        :showAnimation="true"
        v-for="(item, i) in chapterList"
        :key="i"
      >
        <div class="list" v-for="(it, index) in item.list" :key="index">
          {{it.name}}
        </div>
      </collpase-item>
    </collpase>
  </div>
</template>

<script>
import Collpase from './components/Collpase.vue';
import CollpaseItem from './components/CollpaseItem.vue'

export default {
  name: 'App',
  data() {
    return {
      chapterList: [
        {
          name: '标题一',
          list: [
            {
              name: '是是是是是是所'
            },
            {
              name: '啊啊啊啊'
            }
          ]
        },
        {
          name: '标题二',
          list: [
            {
              name: '是是是是是是所'
            },
            {
              name: '啊啊啊啊'
            },
            {
              name: '啊啊啊啊'
            }
          ]
        }
      ]
    }
  },
  components: {
    Collpase,
    CollpaseItem,
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

子组件:

<template>
 <div class="collapse">
  <slot />
 </div>
</template>
<script>
 export default {
  name: 'Collapse',
  props: {
   accordion: {
    type: [Boolean, String],
    default: false
   }
  },
  provide() {
   return {
    collapse: this
   }
  },
  created() {
   this.childrens = []
  },
  methods: {
   onChange() {
    let activeItem = []
    this.childrens.forEach((vm) => {
     if (vm.isOpen) {
      activeItem.push(vm.nameSync)
     }
    })
    this.$emit('change', activeItem)
   }
  }
 }
</script>
<style lang="css" scoped>
 .collapse {
  width: 100%;
  display: flex;
  flex: 1;
  flex-direction: column;
 }
</style>

子组件:

<template>
 <div>
    <div :class="{ 'collapse-disabled': disabled,'collapse-cell--notdisabled': !disabled, 'collapse-cell--open': isOpen,'collapse-cell--hide':!isOpen }" class="collapse-cell">
      <div :class="{ 'collapse-disabled': disabled}" class="collapse-cell__title"  @click="onClick">
        <span class="collapse-cell__title-text">{{ title }}</span>
        <img :class="{ 'active': isOpen, 'active-animation': showAnimation === true }" class="title-arrow" src="https://static-mumway.oss-cn-zhangjiakou.aliyuncs.com/NetworkFrontEnd/wsj/yslbq/btn_dropdown.png"/>
      </div>
      <div :class="{'collapse-cell__content--hide':!isOpen}" class="collapse-cell__content">
        <div :class="{ 'active-animation': showAnimation === true }" class="collapse-cell__wrapper" :style="{'transform':isOpen?'translateY(0)':'translateY(-50%)','-webkit-transform':isOpen?'translateY(0)':'translateY(-50%)'}">
          <slot />
        </div>
      </div>
    </div>
  </div>
</template>

<script>
 export default {
  name: 'UniCollapseItem',
  props: {
   title: {
    // 列表标题
    type: String,
    default: ''
   },
   name: {
    // 唯一标识符
    type: [Number, String],
    default: 0
   },
   disabled: {
    // 是否禁用
    type: Boolean,
    default: false
   },
   showAnimation: {
    // 是否显示动画
    type: Boolean,
    default: false
   },
   open: {
    // 是否展开
    type: Boolean,
    default: false
   },
   thumb: {
    // 缩略图
    type: String,
    default: ''
   }
  },
  data() {
   return {
    isOpen: false
   }
  },
  watch: {
   open(val) {
    this.isOpen = val
   }
  },
  inject: ['collapse'],
  created() {
   this.isOpen = this.open
   this.nameSync = this.name ? this.name : this.collapse.childrens.length
   this.collapse.childrens.push(this)
   if (String(this.collapse.accordion) === 'true') {
    if (this.isOpen) {
     let lastEl = this.collapse.childrens[this.collapse.childrens.length - 2]
     if (lastEl) {
      this.collapse.childrens[this.collapse.childrens.length - 2].isOpen = false
     }
    }
   }
  },
  methods: {
   onClick() {
    if (this.disabled) {
     return
    }
    if (String(this.collapse.accordion) === 'true') {
     this.collapse.childrens.forEach(vm => {
      if (vm === this) {
       return
      }
      vm.isOpen = false
     })
    }
    this.isOpen = !this.isOpen
    this.collapse.onChange && this.collapse.onChange()
    this.$forceUpdate()
   }
  }
 }
</script>

<style lang="css" scoped>
 .collapse-cell {
  flex-direction: column;
  border-color: #f0f0f0;
  border-bottom-width: 1px;
 }
 .collapse-cell--open {
  background-color: #fff;
 }
 .collapse-disabled {
  cursor: not-allowed !important;
 }
 .collapse-cell--hide {
  height: 48px;
 }
 .active-animation {
  transition-property: transform;
  transition-duration: 0.3s;
  transition-timing-function: ease;
 }

 .collapse-cell__title {
  border-bottom: 1px solid #f0f0f0;
  padding: 12px 20px;
  position: relative;
  display: flex;
  width: 100%;
  box-sizing: border-box;
  height: 44px;
  line-height: 44px;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  cursor: pointer;
 }
 .collapse-cell__title-img {
  margin-right: 10px;
 }
 .title-arrow {
  width: 22px;
  height: 14px;
 }
 .active {
  transform: rotate(180deg);
 }
 .collapse-cell__title-text {
  flex: 1;
  font-size: 16px;
  margin-right: 16px;
  white-space: nowrap;
  color: #333333;
    font-weight: bold;
  lines: 1;
  overflow: hidden;
  text-overflow: ellipsis;
 }
 .collapse-cell__content {
  overflow-x: hidden;
 }
 .collapse-cell__wrapper {
  display: flex;
  flex-direction: column;
 }
 .collapse-cell__content--hide {
  height: 0px;
  line-height: 0px;
 }
</style>

您可能感兴趣的文章:

相关文章