vue2.0 自定义 折叠列表(Accordion)组件
1.自定义 折叠列表
Accordion.vue
(1)sass 版本
<!-- 折叠列表 组件 --> <template> <nav :class="$style.accWrapper"> <div :class="$style.accTitle" @click="toggleList"> <span>{{ title.area }}</span> <span>当前人数:{{ title.num }}人</span> <span>总人数:{{ title.sum }}人</span> <img src="../assets/img/arrow_right.png" alt="chevron" :class="[{ [$style.open_menu]: isDisplay, [$style.close_menu]: !isDisplay }, $style.accChevron]" /> </div> <ul :class="[{ [$style.maxHeight]: isDisplay }, $style.accList]"> <li :class="$style.accListItem" v-for="item in list"> <span>{{ item.area }}</span> <span>当前人数:{{ item.num }}人</span> <span>总人数:{{ item.sum }}人</span> </li> </ul> </nav> </template> <script> export default { data () { return { isDisplay: false } }, props: { title: { type: Object, default(){ return {} } }, list: { type: Array, required: true } }, methods: { toggleList () { this.isDisplay = !this.isDisplay } } } </script> <style lang="scss" module> .accWrapper { display:flex; flex-direction: column; } .accTitle { display: flex; justify-content: space-between; align-items: baseline; height: 50px; line-height: 50px; font-size: 16px; background: #eee; text-indent: 1em; cursor: pointer; } .accChevron { width: 20px; margin-right: 15px; } .accList{ list-style: none; padding: 0; margin: 0; font-size: 16px; overflow: hidden; max-height: 0; transition: max-height .5s ease-out; } .accList.maxHeight { max-height: 500px; transition: max-height .5s ease-in; } .accListItem { background-image: url(../assets/img/arrow_right.png); background-repeat: no-repeat; background-size: 20px 20px; background-position: 95% 50%; display: flex; // justify-content: space-between; align-items: baseline; height: 50px; line-height: 50px; font-size: 16px; text-indent: 1em; cursor: pointer; } /* chevron animation */ @keyframes open-menu { to { transform: rotate(90deg); } } @keyframes close-menu { from { transform: rotate(90deg); } to { transform: rotate(0deg); } } .open_menu { animation: open-menu 0.4s ease-out forwards; } .close_menu { animation: close-menu 0.4s ease-out forwards; } </style>
(2)less 版本
<!-- 折叠列表 组件 --> <template> <nav class="accWrapper"> <div class="accTitle" @click="toggleList"> <span>{{ title.area }}</span> <span>当前人数:{{ title.num }}人</span> <span>总人数:{{ title.sum }}人</span> <img src="../assets/img/arrow_right.png" alt="chevron" :class="['accChevron', { 'open_menu': isDisplay, 'close_menu': !isDisplay }]" /> </div> <ul :class="['accList', { 'maxHeight': isDisplay }]"> <li class="accListItem" v-for="item in list"> <span>{{ item.area }}</span> <span>当前人数:{{ item.num }}人</span> <span>总人数:{{ item.sum }}人</span> </li> </ul> </nav> </template> <script> export default { data () { return { isDisplay: false } }, props: { title: { type: Object, default(){ return {} } }, list: { type: Array, required: true } }, methods: { toggleList () { this.isDisplay = !this.isDisplay } } } </script> <style lang="less" scoped> .accWrapper { display:flex; flex-direction: column; } .accTitle { display: flex; justify-content: space-between; align-items: baseline; height: 50px; line-height: 50px; font-size: 16px; background: #eee; text-indent: 1em; cursor: pointer; } .accChevron { width: 20px; margin-right: 15px; } .accList{ list-style: none; padding: 0; margin: 0; font-size: 16px; overflow: hidden; max-height: 0; transition: max-height .5s ease-out; } .accList.maxHeight { max-height: 500px; transition: max-height .5s ease-in; } .accListItem { background-image: url(../assets/img/arrow_right.png); background-repeat: no-repeat; background-size: 20px 20px; background-position: 95% 50%; display: flex; // justify-content: space-between; align-items: baseline; height: 50px; line-height: 50px; font-size: 16px; text-indent: 1em; cursor: pointer; } /* chevron animation */ @keyframes open-menu { to { transform: rotate(90deg); } } @keyframes close-menu { from { transform: rotate(90deg); } to { transform: rotate(0deg); } } .open_menu { animation: open-menu 0.4s ease-out forwards; } .close_menu { animation: close-menu 0.4s ease-out forwards; } </style>
2.页面调用
Fold.vue
<!-- 折叠列表 --> <template> <div> <!-- 标题栏 --> <mt-header title="折叠列表"> <router-link to="/" slot="left"> <mt-button icon="back">返回</mt-button> </router-link> </mt-header> <!-- 列表 --> <accordion v-for="(item,index) in dataList" :key="item.id" :title="item" :list="item.child"> </accordion> </div> </template> <script> import Accordion from '../components/Accordion' export default { name: 'Fold', components: { Accordion, }, data(){ return { dataList:[ {"area":"深圳","num":"10","sum":"30","child":[ {"area":"罗湖","num":"20","sum":"20"}, {"area":"福田","num":"20","sum":"20"}, {"area":"南山","num":"20","sum":"20"} ]}, {"area":"广州","num":"10","sum":"30","child":[ {"area":"白云","num":"20","sum":"20"}, {"area":"福田","num":"20","sum":"20"}, {"area":"南山","num":"20","sum":"20"} ]} ] } } } </script> <style lang="scss" scoped> // </style>
3.效果图