Динамический Абсолютный Элемент Древовидного Представления (вверху слева) в Vue Js - PullRequest
0 голосов
/ 14 мая 2018

Я хочу сделать Treeview следующим образом:

A 
|--B
|  |--BC1
|  |   |--BC1-S
|  |      |--BC1-1
|  |      |--BC1-2
|  |__BC2
|      |--BC2-S
|         |--BC2-1
|         |--BC2-2
|--G
   |--GC1
       |--GC1-S1
       |  |--GC1-1
       |  |--GC1-2
       |
       |--GC1-S2
          |--GC1-3
          |--GC1-4

У меня есть данные, полученные из API, вот так: (ID, Root, Attribute, Depth)

datas: [ 
  [1,  0,  'A',     0],
  [2,  1,  'B',     1], 
  [3,  2,  'BC1',   2],
  [4,  3,  'BC1-S', 3],
  [5,  4,  'BC1-1', 4],
  [6,  4,  'BC1-2', 4],
  [7,  2,  'BC2',   2],
  [8,  7,  'BC2-S', 3],
  [9,  8,  'BC2-1', 4],
  [10, 8,  'BC2-2', 4],
  [11, 1,  'G',     1],
  [12, 11, 'GC1',   2],
  [13, 12, 'GC1-S1',3],
  [14, 13, 'GC1-1', 4],
  [15, 13, 'GC1-2', 4],
  [16, 11, 'GC1-S2',3],
  [17, 16, 'GC1-3', 4],
  [18, 16, 'GC1-4', 4]
]

Шаблон:

<tr v-for="data in datas" :key="data[0]">
<td>
  <div v-if="data[3] == 0" class="tt tt-parent" style="left: 0px;">
    <div class="content">{{ data[2] }}</div>
  </div>

  <div v-else-if="data[3] == 1" class="tt tt-parent" style="left: 47px;">
    <div class="tail" style="height: 26px; width: 47px; left: -23.5px;"></div>
    <div class="content">{{ data[2] }}</div>
  </div>

  <div v-else-if="data[3] == 2" class="tt tt-parent" style="left: 95px;">
    <div class="tail" style="height: 26px; width: 47px; left: -23.5px;"></div>
    <div class="content">{{ data[2] }}</div>
  </div>

  <div v-else-if="data[3] == 3" class="tt tt-parent" style="left: 143px;">
    <div class="tail" style="height: 26px; width: 47px; left: -23.5px;"></div>
    <div class="content">{{ data[2] }}</div>
  </div>

  <div v-else-if="data[6] == 4" class="tt" style="left: 191px;">
    <div class="tail" style="height: 26px; width: 47px; left: -23.5px;"></div>
    <div class="content">{{ data[2] }}</div>
  </div>
</td> 
</tr>

CSS:

.tt-table div.tt {
    display:inline-block;
    position:relative;
}

.tt-table div.tt div.content {
    border:1px gray solid;
    border-radius: 2px;
    z-index: 10;
    padding:0 4px 0 5px;
    position:relative;
    background-color: #dbffbe;
    width: 100px;
}

.tt-table div.tt div.tail {
    border:2px gray solid;
    border-right: 0;
    border-top: 0;
    position:absolute;
    border-radius: 2px;
    bottom: 11px;
    left: -10px;
    z-index: 0;
}

Привет всем, я хочу создать древовидную структуру следующим образом.

  1. проблема в том, что я не могу соединить линию междуAG, B-BC2, GC1-GC1-S2.
  2. Как создать динамический сценарий, особенно если для данных более 50

Это один изнеудачные примеры:

1 Ответ

0 голосов
/ 14 мая 2018

сначала вам нужно структурировать data в отношения родитель-потомок (используйте внутреннюю функцию сценария java для преобразования данных массива в объект родитель-потомок или их на сервере)

тогда вы можете использовать рекурсивный рендеринг, как показано ниже.

// modified data from array
var data = {
  id: 1,
  name: 'A',
  open: true,  // default open
  children: [{
      name: 'B',
      children: [{
        name: 'BC1',
        children: [{
          name: 'BC1-S',
          children: [{
              name: 'BC1-1'
            },
            {
              name: 'BC1-2'
            }
          ]
        }]
      },{
        name: 'BC2',
        children: [{
          name: 'BC2-S',
          children: [{
              name: 'BC2-1'
            },
            {
              name: 'BC2-2'
            }
          ]
        }]
      }]
    },
    {
      name: 'G',
      children: [{
        name: 'GC1',
        children: [{
          name: 'GC1-S1',
          children: [{
              name: 'GC1-1'
            },
            {
              name: 'GC1-2'
            }
          ]
        },{
          name: 'GC1-S2',
          children: [{
              name: 'GC1-3'
            },
            {
              name: 'GC1-4'
            }
          ]
        }]
      }]
    }
  ]
}

// define the item component
Vue.component('item', {
  template: '#item-template',
  props: {
    model: Object
  },
  data: function() {
    return {
      open: this.model.open
    }
  },
  computed: {
    isFolder: function() {
      return this.model.children &&
        this.model.children.length
    }
  },
  methods: {
    toggle: function() {
      if (this.isFolder) {
        this.open = !this.open
      }
    }
  }
})

new Vue({
  el: '#main',
  data: {
    treeData: data
  }
})
body {
  font-family: Menlo, Consolas, monospace;
  color: #444;
}

.tree-view {}

.tree-view>ul {
  padding-left: 16px;
}

.tree-view li {
  list-style-type: none;
  margin: 0;
  padding: 10px 5px 0;
  position: relative;
}

.tree-view li:last-child {
  margin-bottom: 10px;
}

.tree-view li::after,
.tree-view li::before {
  content: '';
  left: -30px;
  position: absolute;
  right: auto;
}

.tree-view li::before {
  border-left: 1px solid #405567;
  height: calc(100% + 10px);
  top: 0;
  width: 1px;
}

.tree-view li::after {
  border-top: 1px solid #405567;
  height: 20px;
  top: 20px;
  width: 35px;
}

.tree-view .item {
  border: 1px solid #405567;
  border-radius: 2px;
  background-color: #fff;
  display: inline-block;
  padding: 2px 6px;
  text-decoration: none;
  cursor: pointer;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
}

.tree-view .folder {
  background-color: #fbf897;
}

.tree-view>ul>li::after,
.tree-view>ul>li::before {
  border: 0;
}

.tree-view li:last-child::before {
  height: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>

<script type="text/x-template" id="item-template">
  <li>
    <div class="item" :class="{folder: isFolder}" @click="toggle">
      <span v-if="isFolder">{{ open ? '-' : '+' }}</span> {{ model.name }}
    </div>
    <ul v-show="open" v-if="isFolder">
      <item v-for="(model, index) in model.children" :key="index" :model="model">
      </item>
    </ul>
  </li>
</script>

<div class="tree-view" id="main">
  <ul>
    <item :model="treeData">
    </item>
  </ul>
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...