음악, 삶, 개발

Dropdown 메뉴 만들기 : recursion 과 tree 본문

개발 Web/Vue.js 공부방

Dropdown 메뉴 만들기 : recursion 과 tree

Lee_____ 2020. 11. 26. 23:01

< 참고 자료 >

Build A Collapsible Tree Menu With Vue.js Recursive Components

Creating a Recursive Tree Component in Vue

Vue and Recursive Components

트리 뷰 Example

github.com/mikerodham/vue-dropdowns/blob/master/Dropdown.vue


< Dropdown 메뉴란 ? >

Safari 의 책갈피 메뉴

Dropdown 메뉴란 하나 메뉴를 기준으로 여러개의 하위 메뉴를 갖는 UI 이다.

우리가 사용하는 모든 프로그램들에 Dropdown 메뉴는 매우 필수적이며, 이를 Vue 를 사용하여 구현해보자.


< 데이터 구조 >

Dropdown 메뉴를 구현하기위해서는 우선적으로 이를 데이터로 표현해야한다.

위의 Safari 에 책갈피 메뉴를 데이터로 표현해보자.

 

Dropdown 메뉴의 요소를 item 이라고 명명하자.

Dropdown 메뉴의 특징은 최상단 item, 즉 하나의 root item 만을 갖는다는것이다.

위의 그림에서는 책갈피가 root item 이다.

이를 데이터로 표현하면..

const data = {

    item: '책갈피'
    
}

추후 우리는 html 요소를 이 데이터를 통해 랜더링하기위해 재귀함수 (recursive function) 를 사용할것이기때문에,

rootItem 으로 명명하지말라. 

 

그 다음 책갈피 item 을 root 로,

'시작 페이지 보기', '읽기 목록에 추가', '즐겨찾기' 가 있다고 해보자.

이들은 책갈피 item 의 하위 item 들이며, 이를 통틀어 subItems 라고 명명하자.

const data = {

    item: '책갈피',
    subItems : []
    
}

 

subItems 들은 다른 item 들을 포함할것이기때문에 배열이된다.

여기에 들어갈 각 item 들은 item 이라는 key 를 가진 객체여야한다.

이제 item 들을 subItems 에 표현해보면..

const data = {

    item : '책갈피',
    subItems : [
        
        { item : '시작 페이지 보기'}, 
        { item : '읽기 목록에 추가'},
        { item : '즐겨찾기'}
    ]
    
}

이제 첫번째 subItems 들을 추가하였다.

하지만 즐겨찾기에는 또다른 subItems 가 존재한다.

이를 다시 데이터로 나타내면..

const data = {

    item : '책갈피',
    subItems: [
        
        { item : '시작 페이지 보기'}, 
        { item : '읽기 목록에 추가'},
        { 
          
          item : '즐겨찾기', 
          subItems : [

            { item : '개발 관련'},
            { item : 'LEESTRUMENT'},
            { item : '자주 가는 곳들'},
            { item : '관심 제품'},
            { item : 'Tool'},

          ]
          
        }
    ]
    
}

이런식으로, item 에 subItems 이 없는 경우에는

{ item : 'item이름' }

subItems 이 있는 경우에는,

{ item : 'item명', subItems : [ {}, {}, {}, {} ] }

로 표현하면 된다.

 


<!-- TreeView.vue -->

<template>

  <li >

    {{ options.item }}

    <ul v-if="options.subItems !== null">

      <tree-view v-for="subItem in options.subItems" :key="subItem" :options="subItem"></tree-view>

    </ul>

  </li>

</template>

<script>

    export default {

        name: "TreeView", // recursive 하기위해서 필요함. 없으면 error
        props: { options : Object },

    }

</script>
<!-- DropDownMenu.vue -->

<template>

    <div v-text="label"></div>
    <tree-view :options="items"></tree-view>

</template>

<script>

    import TreeView from "./TreeView.vue"

    export default {

        components  : { TreeView },
        props       : { 
            
            label           : String, 
            selectedItem    : String,
            items           : Object,
             
        },
        
    }

</script>
<!-- App.vue -->

<template>

  <drop-down-menu :label="label" :selectedItem="selectedItem" :items="items"></drop-down-menu>

</template>

<script>

  import DropDownMenu from "./components/DropDownMenu.vue"

  export default {

    components: { DropDownMenu },

    setup() {

      const label         = 'Chord'
      const selectedItem  = 'Select Chord!~'
      const items         = { item : "root", subItems : [ { item : 'sub1', subItems : null}, { item : 'sub2', subItems : null} ] }

      return { label, selectedItem, items }

    },

  }

</script>

Lee : 이 접근법은 수정되어야함..

< DropdownMenu.vue >

아래 코드들은 template 에서 recursive loop 을 사용하여 구현하였다.

그냥 외우자..

<!-- DropDownMenu.vue -->

<template>

  <ul>

    <li>{{ item }}</li>

    <drop-down-menu

      v-for     = "each in subItems" 
      :key      = "each"
      :item     = "each.item"
      :subItems = "each.subItems" 
      
    ></drop-down-menu>

  </ul>

</template>

<script>

  export default { 

    name : "DropDownMenu", // 필수로 있어야함! 이렇게 적고, template 에서는 drop-down-menu 로 사용해야함!
    props: [ 'item', 'subItems' ],
    
  }

</script>
<!-- App.vue -->
<template>
  
  <drop-down-menu :item="data.item" :subItems="data.subItems"></drop-down-menu>

</template>

<script>

  import DropDownMenu from './components/DropDownMenu.vue'

  export default {

    components : { DropDownMenu },

    setup() {

      const data = {

          item : '책갈피',
          subItems: [
              
              { item : '시작 페이지 보기'}, 
              { item : '읽기 목록에 추가'},
              { 
                
                item : '즐겨찾기', 
                subItems : [

                  { item : '개발 관련'},
                  { item : 'LEESTRUMENT'},
                  { item : '자주 가는 곳들'},
                  { item : '관심 제품'},
                  { item : 'Tool'},

                ]
                
              }
          ]
          
      }

      return { data }

    }
    
  }

</script>

출력하면..

브라우저
Vue 콘솔
html