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开源中国的笔记里,因为只是自己看所以写的比较乱。把这些代码写下来发布后能给自己一个约束,要写的完整并且能让其他人看得懂,能让自己学到更多的。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,723评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,485评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,998评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,323评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,355评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,079评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,389评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,019评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,519评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,971评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,100评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,738评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,293评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,289评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,517评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,547评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,834评论 2 345

推荐阅读更多精彩内容

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