前言

根据百度前端技术学院2018 MVVM 学院 中的 3.1 用递归的方式实现级联组件 用 vue 实现的

本文章的 github地址


实现思路

1. 组件复用(组件中复用自己)

注意点:

1.1需要有name (使用驼峰命名)

name:'cascadePanel'

<cascade-panel></cascade-panel>

1.2需要有终止条件 v-if

v-if ="activeId>-1 && datalist[activeId].children"

即需要 datalist[activeId]  存在 && datalist[activeId] 有孩子(有选项)

 

2. 具体实现分析

<cascade-panel :datalist="datalist[activeId].children" :activeId="activeId2" v-on:patch="onPatch"></cascade-panel>

1).此时把选中chlidren赋给datalist

2).用v-on:patch="onPatch" 接收子组件的选中值

2.1 v-on:patch="onPatch"函数名字onPatch与根部的须相同,这样才能一级一级往上传,直到送到根部

2.2 判断达到最后一级面板,触发事件,把选中值往上传

if (!this.datalist[this.activeId].children) {
    this.$emit("patch", this.datalist[this.activeId].label);
}

 

2.3 点击这一级菜单,才弹出下一级菜单(只显示下一级)

:activeId="activeId2"  传activeId2

每次点击时传this.activeId2=-1;

都将下一级菜单的activeId 恢复成初始值-1

(否则会出现点到第三级时,回去再点第一级,此时第三级仍然会显示)

 

代码实现

cascade-panel.vue

<template>
    <div class="panel">
        <li v-for="(item,index) in datalist" :key="index" @click="change(index);" :class="[index==activeId?'active':'']">{{item.label}}</li>
      
        <div v-if="activeId>-1 && datalist[activeId].children">
            <cascade-panel :datalist="datalist[activeId].children" :activeId="activeId2" v-on:patch="onPatch"></cascade-panel>
        </div>
    </div>
</template>
<script>
export default {
  name: "cascadePanel",
  props: ["datalist", "activeId"],
  components: {},
  data() {
    return {
      activeId: -1
    };
  },
  methods: {
    change(index) {
      this.activeId2 = -1;
      this.activeId = parseInt(index);
      if (!this.datalist[this.activeId].children) {
        this.$emit("patch", this.datalist[this.activeId].label);
      }

      //点击之后下一个组件显示,activeId初始化-1
    },
    onPatch(val) {
      var checkedVal = this.datalist[this.activeId].label + "/" + val;
      this.$emit("patch", checkedVal);
    }
  }
};
</script>

在最上一层获取选中值

cascade.vue

<template>
  <div class="cascadeWrap">
      <input type="text" @click="handleClick" v-model="checkedValue">
      <cascade-panel :datalist="datalist" v-on:patch="onPatch" v-show="open" id="style"></cascade-panel>
  </div>
</template>
<script>
import cascadePanel from "./cascade-panel.vue";
export default {
  props: ["datalist"],
  components: {
    "cascade-panel": cascadePanel
  },
  data() {
    return {
      open: false,
      checkedValue: ""
    };
  },
  methods: {
    handleClick() {
      this.open = !this.open;
      this.checkedValue = "";
    },
    onPatch(val) {
      // alert(val);
      this.checkedValue = val;
      this.open = false;
    }
  }
};
</script>

 

结束

如果文章对你有帮助,麻烦点赞哦!一起走码农花路~

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐