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.效果图

转载于:https://www.cnblogs.com/crazycode2/p/7919256.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue.js 2.0 中,`v-model` 是一个非常强大的指令,用于实现数据绑定和表单输入的双向数据同步。自定义组件中使用 `v-model` 可以让你的用户输入自动更新组件的内部状态,并反之亦然。 以下是一个简单的自定义组件(例如一个名为 `CustomInput` 的输入框组件)的 `v-model` 示例: ```html <template> <div> <input type="text" v-model="inputValue"> <p>你输入的是: {{ inputValue }}</p> </div> </template> <script> export default { data() { return { inputValue: '', }; }, }; </script> ``` 在这个例子中: - `<input type="text" v-model="inputValue">`:将输入框的值绑定到 `inputValue` 数据属性上,用户在输入框中修改的任何内容都会实时更新 `inputValue`。 - `<p>你输入的是: {{ inputValue }}</p>`:当 `inputValue` 发生变化时,对应的文本也会根据新的值显示。 如果你在父组件中使用这个自定义组件: ```html <template> <div> <custom-input></custom-input> </div> </template> <script> import CustomInput from './CustomInput.vue'; export default { components: { CustomInput, }, }; </script> ``` 并且希望父组件的数据影响子组件,你可以在父组件的数据中设置默认值并传递给子组件: ```html <template> <div> <custom-input :value="parentValue"></custom-input> </div> </template> <script> export default { data() { return { parentValue: '初始值', }; }, components: { CustomInput: { props: ['value'], // 定义接收父组件传入的值 data() { return { inputValue: this.value, // 在子组件中设置默认值 }; }, }, }, }; </script> ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值