【VUEJS】multi condition filtering

 <template id="demo-filter">

  <div class="demo">

    <div class="demo-warp">

      <div class="demo-flex" v-for="(v,k) in getList" :key="k">

        <span class="demo-title">{{v.title}}</span>

        <div class="demo-content">

          <div class="demo-tab" :class="isShow ? 'demo-hide' : ''">

            <span v-for="(val, key) in v.childer" :key="key" :class="{'demo-active': val.active}" @click="tabClick(val,key,k)">{{val.value}}</span>

          </div>

        </div>

        <div class="demo-more" @click="isShow = !isShow" v-if="v.childer.length >= 14">More</div>

      </div>

    </div>

  </div>

</template>

<div id="app">

  <section id="view" cloak>

    <demo-filter :get-list="filterList" @get-sel-data="getFilterSelData" @set-time="setTime"></demo-filter>

    <view-layout :view-data="viewData" width="25%" height="300px" :view-time="viewTime"></view-layout>

    <pre>

    Selected data: {{filterSelData}}

    </pre>

  </section>

  

</div>


* {margin: 0;

padding: 0;

box-sizing: border-box;

}


html,

body,

section {

  width: 100%;

  height: 100%;

}


[v-cloak] {

  display: none;

}


section {

  display: flex;

  flex-direction: column;

}


/* Layout component: start */

.view-warp {

  flex: 1;

  overflow: hidden;

  margin: auto;

  display: flex;

}


.view-box {

  overflow: auto;

  width: 1220px;

  height: 100%;

  display: flex;

  flex-wrap: wrap;

  align-content: flex-start;

  margin: 0 -10px;

}


.view-flex {

  padding: 10px;

  cursor: pointer;

  transition: ease .5s;

  transform-style: preserve-3d;

}


.view-flex:hover {

  transform: translateY(-10px);

  transition: ease .5s;

}


.view-item {

  height: 100%;

  border: 1px solid red;

  display: flex;

}


.view-item>span {

  margin: auto;

}


.view-no-data {

  margin: auto;

}


/* Layout component: end */


/* Filter list: start */

.demo {

  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1);

  margin-bottom: 15px;

  min-height: 140px;

  height: auto !important;

  height: 140px;

}


.demo-warp {

  display: flex;

  max-width: 1200px;

  margin: auto;

  height: 100%;

  flex-direction: column;

  padding: 15px 0;

}


.demo-flex {

  display: flex;

  margin-bottom: 15px;

}


.demo-flex:last-of-type {

  margin-bottom: 0;

}


.demo-title {

  flex-basis: 70px;

  margin-top: 5px;

}


.demo-content {

  display: flex;

  flex: 1;

}


.demo-tab {

  flex: 1;

  margin-right: 15px;

  height: 35px;

  overflow: hidden;

}


.demo-tab span {

  display: inline-block;

  margin: 0 5px 15px 5px;

  cursor: pointer;

  padding: 5px 10px;

  color: #999999;

}


.demo-more {

  margin-top: 5px;

  cursor: pointer;

}


.demo-active {

  background-color: #09F;

  color: white !important;

  border-radius: 3px;

}


.demo-tab span:hover {

  background-color: #09F;

  color: white;

  border-radius: 3px;

}


.demo-hide {

  min-height: 35px;

  height: auto !important;

}


// Filter filter components

Vue.component('demo-filter', {

  template: `#demo-filter`,

  data() {

    return {

      isShow: false

    }

  },

  props: {

    getList: {

      type: Array,

      default: () => []

    }

  },

  methods: {

    tabClick(data, key, k) {

      // Add active ==> true display ʻactive style`

      this.getList[k].childer.map(item => {

        item.active = false

      })

      this.getList[k].childer[key].active = true


      // selected data

      let newArray = []

      this.getList.map(data => {

        data.childer.map(item => {

          if (item.active == true) {

            newArray.push(item)

          }

        })

      })

      this.$emit('get-sel-data', newArray)

      this.$emit('set-time', 0, 1000, true)

    }

  }

})


// Layout components

Vue.component('view-layout', {

  template: `<div class="view-warp">

  <div class="view-box" v-if="!viewTime.time">

  <div class="view-flex" v-for="(v,k) in viewData" :key="k" :style="style">

  <div class="view-item">

  <span>{{v.title}}</span>

  </div>

  </div>

  </div>

  <div class="view-no-data" v-else>{{viewTime.msg}}</div>

  </div>`,

  props: {

    viewData: {

      type: Array,

      default: () => []

    },

    width: {

      type: String,

      default: "25%"

    },

    height: {

      type: String,

      default: "300px"

    },

    viewTime: {

      type: Object,

      default: {

        time: true,

        msg: 'loading...'

      }

    }

  },

  computed: {

    style() {

      return {

        width: `${this.width.replace(/%+/, '')}%`,

        height: `${this.height.replace(/px+/, '')}px`

      }

    }

  }

})


const vm = new Vue({

  el: '#view',

  data() {

    return {

      viewList: [],

      viewTime: {

        time: true,

        msg: 'Data is loading desperately...'

      },

      param: {},

      filterList: [],

      filterSelData: [] // Filter selected data

    }

  },

  created() {

    this.viewList =  [

      {

        "title": "11",

        "value": "Floating Material"

      },

      {

        "title": "22",

        "value": "Floating Material"

      },

      {

        "title": "33",

        "value": "Floating Material"

      },

      {

        "title": "44",

        "value": "Floating Material"

      },

      {

        "title": "55",

        "value": "Floating Material"

      },

      {

        "title": "66",

        "value": "Effect Elements"

      }

    ]


    this.filterList = [

      {

        "title": "classification:",

        "childer": [{

          "value": "All",

          "active": true

        },

                    {

                      "value": "Floating Material",

                      "active": false

                    },

                    {

                      "value": "Effect Elements",

                      "active": false

                    },

                    {

                      "value": "Cartoon hand drawn",

                      "active": false

                    },

                    {

                      "value": "Decorative Pattern",

                      "active": false

                    },

                    {

                      "value": "Icon Elements",

                      "active": false

                    },

                    {

                      "value": "Promotion Label",

                      "active": false

                    },

                    {

                      "value": "Border Texture",

                      "active": false

                    },

                    {

                      "value": "irregular shape",

                      "active": false

                    },

                    {

                      "value": "Emoji package 213123",

                      "active": false

                    },

                    {

                      "value": "Expression Pack 2323",

                      "active": false

                    },

                    {

                      "value": "Expression Pack 1111",

                      "active": false

                    },

                    {

                      "value": "Emoticon 3333",

                      "active": false

                    },

                    {

                      "value": "Emoticon 444",

                      "active": false

                    }

                   ]

      },

      {

        "title": "format:",

        "childer": [{

          "value": "All",

          "active": true

        },

                    {

                      "value": "PSD",

                      "active": false

                    },

                    {

                      "value": "AI",

                      "active": false

                    },

                    {

                      "value": "EPS",

                      "active": false

                    }

                   ]

      },

      {

        "title": "Sort:",

        "childer": [{

          "value": "recommend",

          "active": true

        },

                    {

                      "value": "Hot yesterday",

                      "active": false

                    },

                    {

                      "value": "Newest upload",

                      "active": false

                    },

                    {

                      "value": "Top Downloads",

                      "active": false

                    },

                    {

                      "value": "Popular Collection",

                      "active": false

                    }

                   ]

      }

    ]


  },

  computed:{

    viewData(){

      var vm = this

      return this.viewList.filter(filter =>{

        var data = vm.filterSelData;

        var i;

        for (i = 0; i < data.length; i++) {

          if(filter.value == data[i].value){

            return true

          }

        }

      })

    }

  },

  mounted() {

    this.setTime(1000, 0, false)

  },

  methods: {

    // Encapsulate axios

    setRequest(url, data = {}, method = 'get') {

      return new Promise((resolve, reject) => {

        axios({

          url,

          method,

          data

        }).then(res => {

          resolve(res.data)

        }).catch(err => {

          reject(err)

        })

      })

    },


    // Get the selected value of the filter component

    getFilterSelData(data) {

      this.filterSelData = data

    },


    // Simulate delayed display data view

    setTime(startTime, endTime, bool) {

      setTimeout(() => {

        this.viewTime.time = bool

        setTimeout(() => {

          this.viewTime.time = false

        }, endTime)

      }, startTime)

    }

  }

})

No comments:

Power Is Shifting Rapidly to Indie Creators

The exodus from Twitter since the election is a sign of things to come ͏     ­͏     ­͏     ­͏     ­͏     ­͏     ­͏     ­͏     ­͏     ­͏     ...

Contact Form

Name

Email *

Message *