vue手写列表多级联动

一、项目需求

用户登录后展示条件筛选页面,多层条件筛选,存在单选和多选情况,以及视图样式根据选中情况有相应的变,点击清空按钮后恢复初始状态。效果图如下:
20191215_163317.gif

二、数据分析

列表渲染的数据部分前端写死,部分是从后端接口调取:

// 获取接口数据
mounted () {
    let param = {
      enableFlag: 'Y',
    }
    let promise0 = fetchCarBrand(param)
    let promise1 = fetchSelectTList('APP.CAR.ENERGY_TYPE')
    let promise2 = fetchSelectTList('APP.CAR.DISPLACEMENT')
    let promise3 = fetchSelectTList('APP.CAR.CLOUR')
    let promise4 = fetchSelectTList('APP.CAR.PASSENGERS')
    Promise.all([promise0, promise1, promise2, promise3, promise4]).then(
      res => {
        console.log(res)
        this.carBrandData = res[0].rows
        this.newCarBrandData = this.carBrandData.map(item => {
          return Object.assign(item, { isPiont: false })
        })
        this.energyType = res[1].rows
        this.displacement = res[2].rows
        this.carColor = res[3].rows
        this.persons = res[4].rows
      }
    )
}

(1)三级联动---以车辆品牌为例:
image.png
  • dom结构:
<!-- 一层列表 -->
<li
    :class="{ switch: activeIndex === 1 }"
    class="car-model"
    @click="handleSwitchLiTwo"
  >
    <div
      :class="{
        bluecolor: selectParam.brandList || selectParam.modelList
      }"
    >
      <i
        :class="{
          bluepoint: selectParam.brandList || selectParam.modelList
        }"
      />车辆品牌
    </div>
    <!-- 二层列表 -->
    <ul v-if="isModelShow">
      <li
        v-for="(item, index) in newCarBrandData"
        :key="index"
        @click="selectCarModel(item)"
      >
        <div
          :class="{
            bluecolor:
              selectParam.brandList &&
              selectParam.brandList.find(e => e === item.brandId)
          }"
        >
          <i
            :class="{
              bluepoint: modelMap[item.brandId] && modelMap[item.brandId].length
            }"
          />
          {{ item.brandName }}
        </div>
      </li>
    </ul>
   <!-- 三层列表 -->
    <ul v-if="isModel" class="car-model-child">
      <li
        v-for="(v, i) in newModelData"
        :key="i"
        :class="{
          bluecolor:
            modelMap[v.brandId] && modelMap[v.brandId].includes(v.modelId)
        }"
        @click.stop="handleSelectModel(v)"
      >
        {{ v.modelName }}
      </li>
    </ul>
  </li>

此处将二层列表和三层列表写成并列结构,原本写的是嵌套结构,但由于后来属性控制出现问题,改成了并列结构。
同时针对动态类名的控制这里使用的是我点击选中后生成的条件列表数组去控制,如果用boolean值就会有一堆的变量需要在不同阶段去改变,很繁琐。
首先一层列表的切换通过判断当前点击下标是否等于该元素在列表中的下标相等,来控制状态。关于tab切换操作方法可参考vue写tab切换

  • 接下来的事件处理才是实现这个功能的重点:
  • 第二级列表的点击事件
// 品牌选择
    selectCarModel (item) {
      this.isModel = true
      // 判断筛选参数里是否存在该列表属性,若没有给一个初始空数组
      if (!this.selectParam.brandList) this.selectParam.brandList = []
     // 若存在则先判断是首次点击选中还是要再次点击取消
      if (this.selectParam.brandList.indexOf(item.brandId) > -1) {
        // 再次点击取消操作
        this.newModelData = []  // 清空第三层列表
        // 过滤掉对应品牌列表里的当前点击项
        this.selectParam.brandList = this.selectParam.brandList.filter(
          i => i !== item.brandId
        )
      } else {
        // 点击选中操作 
       // 设置第三层列表项的数据
        this.newModelData = item.modelList
       // 向对应品牌列表里添加当前点击的品牌id
        this.selectParam.brandList.push(item.brandId)
      }
      // 如果品牌列表为空
      if (this.selectParam.brandList.length === 0) {
        delete this.selectParam.brandList  // 删除筛选参数中的品牌列表属性
        this.isModel = false  // 隐藏第三层列表
      }
      this.$forceUpdate()  // 强制页面更新(重点)
    },
  • 第三级列表的点击事件
    其实实现该模块最难得点就在于这第三层列表要与第二层以及第一层列表的关联,此处我采用的做法是创建一个类似Map结构的对象属性来存选中的数据,利用第三层列表与第二层列表之间的共同的属性brandId作为属性,将选中的modelId存到对应的brandId中,每次点击就判断该map对象下是否存在该modelId,存在则过滤掉不存在则添加。当某个brandId为空是则要删除该属性,最终还要将改对象解构成数组拼接到筛选接口的参数里。
 const mapList = {
     brandId1:[modelId1,model2,...],
     brandId2:[modelId1,model2,...],
     ...
}

上代码:

// 车型选择
    handleSelectModel (item) {
      if (!this.selectParam.modelList) this.selectParam.modelList = []
      if (!this.modelMap[item.brandId]) this.modelMap[item.brandId] = []
      if (this.modelMap[item.brandId].indexOf(item.modelId) > -1) {
        this.modelMap[item.brandId] = this.modelMap[item.brandId].filter(
          i => i !== item.modelId
        )
        if (this.modelMap[item.brandId].length === 0) {
          delete this.modelMap[item.brandId]
        }
      } else {
        this.modelMap[item.brandId].push(item.modelId)
      }
      let modelList = Object.values(this.modelMap)
      if (modelList.length === 0) {
        delete this.selectParam.modelList
      } else {
        this.selectParam.modelList = [].concat(...modelList)
      }
      this.$forceUpdate()
    },

总结

当拿到一个复杂的页面时首先要分析业务需求理清业务逻辑,然后根据接口数据格式去构思页面结构,这样子写起来相对轻松一点。

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

推荐阅读更多精彩内容

  • 专业考题类型管理运行工作负责人一般作业考题内容选项A选项B选项C选项D选项E选项F正确答案 变电单选GYSZ本规程...
    小白兔去钓鱼阅读 8,970评论 0 13
  • 元符三年,宋徽宗即位。改国号为建中靖国。任用蔡京为相,穷奢极侈,民不聊生。宣和元年,宋江率众起于水泊梁山。 白云悠...
    你的荣光阅读 4,349评论 4 13
  • 日更第45天 昨天晚饭两个小时后,正趴在家里的吧台上做功课,突然没有精神,就像皮球泄了气,很快就感觉到胃里翻搅、恶...
    花枝笑阅读 276评论 0 3
  • 阳光明媚,万里无云…… 期待康巴什第一幼儿园苗苗二班的小朋友vs大朋友参观和效鄂电,感受和效文化,一切准备就绪……...
    天使精灵的生活阅读 546评论 0 3