IT이야기

확인란 및 드래그 드롭이 있는 트리 구현

cyworld 2022. 4. 25. 21:46
반응형

확인란 및 드래그 드롭이 있는 트리 구현

나는 체크박스와 드래그 앤 드롭이 있는 Vue에서 트리 뷰를 구현하려고 한다.그러나 나는 어디서부터 시작해야 할지 모르겠다.

확인란을 구현했지만 부모가 모든 자식을 선택하도록 선택되었을 때, 그리고 모든 자식을 선택하여 부모를 선택했을 때 지원을 추가하는 방법을 모르겠다.

또한 나는 드래그 앤 드롭에 문제가 있어, 나는 vue-draggable을 불러보았지만 어떻게 구현해야 할지 모르겠어.

내가 구현하려고 하는 것은 다음과 같은 것이다.

https://ej2.syncfusion.com/vue/documentation/treeview/check-box/

여기 나의 샌드박스가 있는데, 내가 가까스로 구현한 것은 다음과 같다.

https://codesandbox.io/s/immutable-cookies-8lxxf

나는 아래에 있는 재귀적 구성요소를 사용하여 Vue와 함께 이것을 시도해 보았다.부모로부터 모든 자식을 선택할 수 있는 방법과 vue-draggable을 사용할 수 있는 방법을 보여준다(동일한 계층에서만 끌 수 있음).좋은 출발점이 될 거야, 몇 가지 수정이 필요해.

편집:

여러 단계의 드래그 앤 드롭을 수용하기 위해, 나는 드래그 게이지가 같은 그룹에 있도록 코드를 편집했다.빨리 테스트해 봤는데 컨셉이 맞긴 한데 아직 수정이 좀 필요해.중첩된 vue-draggable에 대한 지원은 여기에서 찾을 수 있으며, GitHub에 있는 JSFiddle의 포크를 만들어 어떻게 중첩된 vue-dragggable을 구현했는지 볼 수 있다.

let tree = {
  draggableOptions: {group: 'share'},
  label: 'root',
  selected: false,
  nodes: [
    {
      label: 'item1',
      selected: false,
      nodes: [
        {
          label: 'item1.1',
          selected: false
        },
        {
          label: 'item1.2',
          selected: false,
          nodes: [
            {
              label: 'item1.2.1',
              selected: false
            }
          ]
        }
      ]
    }, 
    {
      label: 'item2',
      selected: false
    }
  ]
}

Vue.component('tree-menu', { 
  template: '#tree-menu',
  props: [ 'nodes', 'label', 'depth', 'selected' ],
  data() {
     return {
       showChildren: false
     }
  },
  computed: {
    iconClasses() {
      return {
        'fa-plus-square-o': !this.showChildren,
        'fa-minus-square-o': this.showChildren
      }
    },
    labelClasses() {
      return { 'has-children': this.nodes }
    },
    indent() {
      return { transform: `translate(${this.depth * 50}px)` }
    }
  },
  methods: {
    toggleChildren() {
       this.showChildren = !this.showChildren;
    
    },
    tickChildren(ev) {
      this.selected = !this.selected;  
      this.tickRecursive(this);
    },
    tickRecursive(node) {
       if(node.nodes && node.nodes.length)
          node.nodes.forEach(x => {
            x.selected = this.selected;
            this.tickRecursive(x);
          });
    }
  }
});

new Vue({
  el: '#app',
  data: {
    tree
  }
})
body {
  font-family: "Open Sans", sans-serif;
  font-size: 18px;
  font-weight: 300;
  line-height: 1em;
}

.container {
  padding-left: 5rem;
  padding-right: 5rem;
  margin: 0 auto;
}

.tree-menu {
  .label-wrapper {
    padding-bottom: 10px;
    margin-bottom: 10px;
    border-bottom: 1px solid #ccc;
    .has-children {
      cursor: pointer;
    }
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js">
</script>
<script src="https://cdn.jsdelivr.net/npm/sortablejs@1.7.0/Sortable.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Vue.Draggable/2.16.0/vuedraggable.min.js"></script>


<div class="container">
  <h4>Implement Tree with checkboxes and drag drop<br/><small>(Using Vue, Recursive Component, Vue Draggable)</small><br /><small><a href="https://stackoverflow.com/questions/60260675/implement-tree-with-checkboxes-and-drag-drop" target="_blank">For StackOverflow Question</a></small></h4>
  <div id="app">
   
  <tree-menu 
             :nodes="tree.nodes" 
             :depth="0"   
             :label="tree.label"
             :selected="tree.selected"
             ></tree-menu>
       
 
  </div>
    
</div>


<script type="text/x-template" id="tree-menu">

  <div class="tree-menu">
    <div class="label-wrapper">
      <div :style="indent" :class="labelClasses" @click.stop="toggleChildren">
        <i v-if="nodes" class="fa" :class="iconClasses"></i>
        <input type="checkbox" :checked="selected" @input="tickChildren" @click.stop />
        {{label}}
      </div>
    </div>
    
        <draggable v-model="nodes" :options="{group:{ name:'g1'}}">    
    <tree-menu 
      v-if="showChildren"
      v-for="node in nodes" 
      :nodes="node.nodes" 
      :label="node.label"
      :depth="depth + 1"
      :selected="node.selected"
      :key="node"
    >
    </tree-menu>
            </draggable>

  </div>

</script>

이 예를 확인하십시오.그들은 당신이 시작해야 할 모든 것을 실행했다.https://vuejsexamples.com/tree-and-multi-select-component-based-on-vue-js-2/

참조URL: https://stackoverflow.com/questions/60260675/implement-tree-with-checkboxes-and-drag-drop

반응형