vue移动端筛选组件

最近的项目中使用筛选写的比较多,每次都要做一些修改才能用到项目上,而且还要看一看代码才能改动。这次又用到,就顺便写成不依赖其他UI框架,下次使用时方便直接引用,再也不想造轮子了!👀

先出效果

简单录屏

组件代码

<template>
  <div class="filter-box">
    <div class="filter flex-row">
      <p v-for="(v, k) in data" :key="k" :class="filterIndex==k? 'active':''" @click="itemClicked(k)">{{v.name}}</p>
    </div>
    <div class="filter-overlay" :class="filterShow? 'active':''" @click="filterShow=false; filterIndex='-1'">
      <div v-if="filterShow" class="filter-column">
        <div v-for="(v, k) in data" :key="k">
          <block v-if="k==filterIndex">
            <p v-for="(vv, kk) in v['options']" :key="kk" :class="filterSelect[v.key] == vv.key ?'active':''" @click.stop="selectItem(v.key ,vv.key)">
              <span>{{vv.name}}</span>
            </p>
          </block>
        </div>
      </div>
    </div>
    
  </div>
</template>

<script>
export default {
  data() {
    return {

      data: [],

      // 当前点击选中的筛选类目
      filterIndex: "-1",

      // 是否展开筛选项
      filterShow: false,

      //已选中的项
      filterSelect: {
      }
    }
  },
  // filterData:所有的数据(必填参数)   currenSelect:已选在数据(可选参数)
  props: ['filterData', 'currenSelect'],
  onLoad() {
    
    var total = this.filterData;
    console.log(total);
    if (total) {
      this.data = this.filterData;
      // 初始化默认选中的选项
      total.forEach(element => {
        var key = element['key'];
        console.log(key);
        var value = element['options'] ? element['options'][0]["key"]: "";
        this.filterSelect[key] = value;
      });
    }
  },
  methods: {
    // 筛选条目被点击
    itemClicked(k) {
      this.filterIndex = k;
      if (!this.filterShow) {
        this.filterShow = true;
      }
    }, 

    // 选中了某一个选项
    selectItem(k, kk) {
      this.filterSelect[k] = kk;
      this.$emit("select", this.filterSelect);
      this.filterShow = false;
      this.filterIndex = "-1";
    }

  }
}
</script>

<style scoped>
.filter-box .filter {
  height: 45px;
  z-index: 101;
  background-color: #fff;
}
.filter-box .filter p {
  text-align: center;
  flex: 1;
  text-indent: -5px;
}
.filter-box .filter p::after {
  content: "";
  display: inline-block;
  width: 4px;
  height: 4px;
  border-left: solid 1px #797979;
  border-top: solid 1px #797979;
  transform: rotate(-135deg);
  position: relative;
  top: -3px;
  left: 5px;
  transition: all .3s ease 0s;
}
.filter-box .filter p.active::after {
  transform: rotate(45deg);
  top: 0;
}
.filter-box .filter-overlay {
  position: fixed;
  width: 100%;
  height: 0;
  top: 45px;
  left: 0;
  background-color: transparent;
  transition: background-color 0.5s ease;
  z-index: 100;
}
.filter-box .filter-overlay.active {
  background-color: rgba(0, 0, 0, 0.6);
  height: 100%;
}
.filter-box .filter-column {
  z-index: 101;
  background-color: #fff;
}
.filter-box .filter-column p {
  height: 40px;
  line-height: 40px;
  padding-left: 20px;
}
.filter-box .filter-column p span {
  font-size: 16px;
  color: #aaa;
}

.filter-box .filter-column p.active{
  background: #f8f8fa;
  color: #4b4b4b;
}
</style>

组件使用

// 模板引用 
<template>
  <div class="job index">
    <Filter :filterData="filterData" @select="selectItem"></Filter>
  </div>
</template>

如果需要设置默认参数 可以使用currenSelect

<Filter :filterData="filterData" :currenSelect="currenSelect" @select="selectItem"></Filter>
  //JS:
  mehtods: {
    setFilter() {
      var data = [
        {
          name: '经验', 
          key:'jingyan', 
          options: [
            {"key": "0", "name": "不限"},
            {"key": "1", "name": "应届生"}, 
            {"key": "2", "name": "1年以内"}, 
            {"key": "3", "name": "1-3年"}
          ]
        },
        {
          name: '学历', 
          key:'xueli', 
          options: [
            {"key": "0", "name": "不限"},
            {"key": "1", "name": "初中及以下"}, 
            {"key": "2", "name": "中专"}, 
            {"key": "3", "name": "高中"}
          ]
        },
        {
          name: '薪资', 
          key:'xinzi', 
          options: [
            {"key": "0", "name": "不限"},
            {"key": "1", "name": "3K以下"}, 
            {"key": "2", "name": "3-5K"}, 
            {"key": "3", "name": "5-8K"}
          ]
        },
        {
          name: '经验', 
          key:'jingyan', 
          options: [
            {"key": "0", "name": "不限"},
            {"key": "1", "name": "无经验"}, 
            {"key": "2", "name": "1年以内"}, 
            {"key": "3", "name": "1-3年"}
          ]
        },
        {
          name: '行业', 
          key:'hangye', 
          options: [
            {"key": "0", "name": "不限"},
            {"key": "1", "name": "金融"}, 
            {"key": "2", "name": "互联网"}, 
            {"key": "3", "name": "服务"}
          ]
        },
      ];
      this.filterData = data;
      // 如果想默认选中值。不设置则默认选中第一项
      this.currenSelect = {
        'xinzi': "3"
      }

    },
    // 筛选中某项
    selectItem(query) {
      console.log(query);
      // 根据业务需要进行数据请求即可
      // 打印出对象: {jingyan: "0", xueli: "0", xinzi: "2", hangye: "0"} 
    },
  }

结语

前端的轮子还是比较多的,需要经常总结的。之前经常看别人写博客,之前一直没有静下来写,只是随手记在OSChina开源中国的笔记里,因为只是自己看所以写的比较乱。把这些代码写下来发布后能给自己一个约束,要写的完整并且能让其他人看得懂,能让自己学到更多的。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 最近在学习vue.js的时候发现,vue的组件化的思想对于编写代码是一个非常有用的事情。 首先为什么需要组件化? ...
    拂晓的云阅读 12,006评论 6 23
  • 前言 您将在本文当中了解到,往网页中添加数据,从传统的dom操作过渡到数据层操作,实现同一个目标,两种不同的方式....
    itclanCoder阅读 26,115评论 1 12
  • 巴厘岛瑜伽课的第三天, “死亡“轻巧地走到了我身边。 幸运的我, 从小到大没有经历过身边亲人的生老病死。谈及人的“...
    Songbei阅读 1,878评论 0 0
  • 富平柿子(一) 嘉果玲珑里外红, 肉丰皮嫩汁饴浓。 金秋天谷珍馐味, 胜比琼浆醉友朋。 (“天谷”指诸如稻、谷、高...
    上元鸿舍主人阅读 5,249评论 22 35
  • 【美食多美味】兰州,错过了一碗热腾腾的兰州拉面,却在中山桥桥头偶遇了“甜胚子”,只一勺,就迷住了老夏…… 这是一种...
    拈花老夏阅读 4,021评论 0 0