• 树形数据结构实现平铺展示


    后端返回的数据是树形结构要实现这种类似平铺树的结构

    基本思路:取出最后两级,取出每一级的所有祖先节点

     // 只获取最后两级得数据
        lastLevelData (data) {
          let that = this
          let arr = []
          data = that._.cloneDeep(data) || []
          data.forEach(el => {
            // el是二级
            if (el.children && el.children.length > 0) {
              if (el.children[0].selectAble && el.children[0].isBottomLevel) {
                that.addAllCheck(el)
              }
              go(el)//递归
            } else {
              arr.push(el)
            }
          })
          function go (item) {
            let p = item
            item.children.forEach(child => {
              child.parent = p
              if (child.children && child.children.length > 0) {
                if (child.children[0].isBottomLevel) {
                  that.addAllCheck(child)
                }
                go(child)
              } else {
                let key = child.parent && child.parent.key // 第三级无子节点
                let str = ''
                if (key) {
                  str = key.replace('_', '')
                }
                if (child.isBottomLevel && str.indexOf('_') === -1) {
                  let deep = that._.cloneDeep(p)
                  deep.children = []
                  deep.children.push(child)
                  that.addAllCheck(deep) //
                  arr.push(deep)
                } else {
                  arr.push(p)
                }
              }
            })
          }
          let obj = {}
    //去掉第一级的标签路径名 let firstlabel = [ '定制标签_', '设备信息_', '自然属性_', '社会属性_', '兴趣偏好_', '资产信息_', '消费信息_', '位置信息_', '产品功能偏好' ] function removeFirst (str) { firstlabel.forEach(item => { if (str.startsWith(item)) { str = str.replace(item, '') return str } }) return str } arr = arr.reduce((cur, next) => { next.fullName = removeFirst(next.fullTagName) if (next.fullName.indexOf('_') === -1) { next.firstLevel = true } else { next.firstLevel = false } if (!obj[next.key]) { obj[next.key] = true cur.push(next) } return cur }, []) arr.forEach(element => { let result = [] let data = element while (data.parent) { data.parent.children = [] result.push(data.parent) // 把它父亲的label存在 data = data.parent } result = result.filter(obj => { if (obj && obj.key) { return obj } }) element.parent = result.reverse() }) this.finalShowData = arr console.log(arr) },

     祖父组件

    <right-childs-tree
                        :treeData="finalShowData"
                        v-model="ids"
                        @checkAll-label="checkAllLabel"
                        @addLabelChange="getAddLabelKeys"
                        :addLabelDataKeys="addLabelDataKeys"
                        :collectDataKeys="collectDataKeys"
                        @collection-change="
                          () => {
                            getCollectionKeys();
                          }
                        "
                      ></right-childs-tree>
    

    Bus.js  

    //由于孙子组件采用了模版递归并有复杂的交互操作只能通过Bus的方式向祖父组件传递事件
    import Vue from "vue"; export default new Vue();

      父组件

    <template>
      <ul>
        <treenode
          v-for="(model, index) in treeData"
          :model="model"
          :key="index"
          :ids="ids"
          :addLabelDataKeys="addLabelDataKeys"
          :collectDataKeys="collectDataKeys"
        >
        </treenode>
      </ul>
    </template>
    <script>
    import rightChilds from "./RightChilds.vue";
    import Bus from "@/data/bus.js";
    export default {
      name: "Tree",
      model: {
        prop: "ids",
        event: "change"
      },
      props: {
        treeData: {
          type: Array,
          default: function() {
            return [];
          }
        },
        ids: {
          type: Array,
          default: function() {
            return [];
          }
        },
        collectDataKeys: {
          type: Array,
          default: function() {
            return [];
          }
        },
        addLabelDataKeys: {
          type: Array,
          default: function() {
            return [];
          }
        }
      },
      components: {
        treenode: rightChilds
      },
      created() {
        let that = this;
        Bus.$on("check-allData", target => {
          that.$emit("checkAll-label", target);
        });
        Bus.$on("addLabel-change", target => {
          that.$emit("addLabelChange", target);
        });
        Bus.$on("collectionChange", target => {
          that.$emit("collection-change", target);
        });
      }
    };
    </script>
    

      孙子组件

    //模版递归
    <template> <li class="tree choicenesChilds" :class="{ sub_tree_all: model.children.length == 0 ? true : false }"> <div v-if="model.children && model.children.length == 0" class="label-container"> <!-- 这里显示第一级的标签名 --> <span v-if="model.firstLevel"> <span class="parent-name">{{ model.label }}</span> </span> <span v-else class="third-label"> <span class="third-line" v-if="model.label !== '全选'">|</span> <span v-if="model.label === '全选'" class="child-name" @click.stop.prevent="allLabel(model)">{{ model.label }}</span> <span v-else> <span slot="reference" class="child-name">{{ model.label }}</span> </span> </span> </div> <div v-else class="label-container"> <ul v-if="model.parent.length > 0"> <li v-for="p in model.parent" :key="p.key" class="parent-name">// <span class="">{{ p.label }}</span> <img src="~@/assets/images/choicenes/right.png" width="12" height="12" class="direction" /> </li> <li class="parent-name"> <span slot="reference" class="">{{ model.label }}</span> </li> </ul> <span v-else> <span slot="reference" class="parent-name">{{ model.label }}</span> </span> <!-- 这里显示父节点 --> </div> <ul> <tree-node v-for="(subModel, index) in model.children" :model="subModel" :ids="ids" :key="index" ></tree-node> </ul> </li> </template> <script> import Bus from "@/data/bus.js"; import apis from "@/api/apis"; import network from "@/api/network"; import { choicenesMixin } from "@/data/choicenesTreeStructureMixin.js"; export default { name: "TreeNode", mixins: [choicenesMixin], props: { ids: { type: Array, default: function() { return []; } }, model: { type: Object, default: function() { return {}; } } }, methods: { allLabel(data) { //去掉第一个全选数据 if (data.otherBrother && data.otherBrother.length > 1) { let brother = [...data.otherBrother]; let allData = brother.splice(1); Bus.$emit("check-allData", allData); } }, addHotLabel(labelData) { Bus.$emit("addLabel-change", labelData); }, collectionChangeFunc() { Bus.$emit("collectionChange"); // 收藏后调用获取所有收藏的key }, } } }; </script> <style lang="scss" scoped="scoped"> @import "~@/styles/variables.scss"; .choicenesChilds { color: #000; height: 100%; .label-container { font-size: 14px; font-weight: 500; height: 100%; color: rgba(142, 142, 163, 1); .selectedLabelRow { background: #d1d9ff; } .el-row { margin-bottom: 0; } li { text-decoration: none; list-style: none; //去掉li前面的圆点 display: inline; //让li横向排列 } .parent-name { font-family: MicrosoftYaHei; font-size: 16px; color: #33353f; line-height: 16px; margin-top: 24px; display: inline-block; &:hover { color: $colorPrimary; cursor: pointer; } .direction { margin: 0 12px; } } .child-name { display: inline-block; font-size: 14px; color: #626574; margin-top: 16px; &:hover { color: $colorPrimary; cursor: pointer; } } .third-label { 100%; display: -webkit-box; -webkit-box-orient: vertical; padding-left: 16px; // -webkit-line-clamp: 4; // text-emphasis: none; // text-overflow: ellipsis; max-height: 150px; overflow: hidden; font-weight: 500; line-height: 21px; .third-line { padding: 0 16px 0 0; } } } } </style> <style lang="scss"> .popover { box-shadow: 1px 2px 13px 0px rgba(221, 237, 224, 0.35); .popover-item { cursor: pointer; padding: 5px 0; color: #bebed7; } .popover-item:hover { color: #415fff; } } .choicenesChilds { .el-card__body { padding: 0; } .el-row { margin-bottom: 20px; &:last-child { margin-bottom: 0; } } .el-col { border-radius: 4px; padding: 0; margin: 0; } } .tree { margin-top: 5px; .sub_tree_all { content: ""; display: inline-block; clear: both; .single_btn { float: left; } } } </style>

      

  • 相关阅读:
    学英语舌尖效应(转)
    winform程序防止重复运行
    label字符自动换行(转自网络)
    C# WINFORM中的combobox.items.add实现像web开发那样,添加显示内容text和实际value值
    三极管开关电路设计(转)
    ASPNET+ArcGIS+Flex初次使用笔记
    转:oracle日期函数集锦
    网站开发人员应该知道的62件事
    cassandra的安装与使用
    datejs一个很好用的时间日期JavaScript组件
  • 原文地址:https://www.cnblogs.com/ihuangqing/p/12541277.html
Copyright © 2020-2023  润新知