Как правильно отображать массив детей в опциях выбора тегов - PullRequest
1 голос
/ 26 июня 2019

У меня есть пользовательский массив данных с древовидной структурой для опций выбора:

[
  {
    "id": 1,
    "name": "Parent 1",
    "children": [
      {
        "id": 2,
        "name": "Parent 1 - Children 1"
      },
      {
        "id": 3,
        "name": "Parent 1 - Children 2"
      }
    ]
  },
  {
    "id": 4,
    "name": "Parent 2",
    "children": []
  },
  {
    "id": 5,
    "name": "Parent 3",
    "children": [
      {
        "id": 6,
        "name": "Parent 3 - Children 1",
        "children": [
          {
            "id": 7,
            "name": "Parent 3 -> Children 1 -> Children 1"
          },
          {
            "id": 8,
            "name": "Parent 3 -> Children 1 -> Children 2"
          },
        ]
      }
    ]
  }
]

Как я могу отобразить свой древовидный массив внутри опций тега <select>, как это:

<select>
  <option value="1">Parent 1</option>
  <option value="2">--Children 1</option>
  <option value="3">--Children 2</option>
  <option value="4">Parent 2</option>
  <option value="5">Parent 3</option>
  <option value="6">--Children 1</option>
  <option value="7">----Children 1</option>
  <option value="8">----Children 2</option>
</select>

Iпо логике не мог решить эту проблему.Я обычно показывал варианты в Vue.js так:

<select class="form-control">
  <option v-for="option in selectOptions">{{option}}</option>
</select>

Ответы [ 2 ]

1 голос
/ 26 июня 2019

Как то так?

new Vue({
  el: '#app',
  data() {
    return {
      options: getData(),
      selected: null
    }
  },
  computed: {
    selectOptions() {
      const tree = this.options
      const flat = []

      add(this.options, '')

      return flat

      function add(nodes, prefix) {
        nodes.forEach(node => {
          flat.push({
            ...node,
            name: prefix + node.name
          })

          add(node.children || [], prefix + '- ')
        })
      }
    }
  }
})

function getData() {
  return [{
      "id": 1,
      "name": "Parent 1",
      "children": [{
          "id": 2,
          "name": "Parent 1 - Children 1"
        },
        {
          "id": 3,
          "name": "Parent 1 - Children 2"
        }
      ]
    },
    {
      "id": 4,
      "name": "Parent 2",
      "children": []
    },
    {
      "id": 5,
      "name": "Parent 3",
      "children": [{
        "id": 6,
        "name": "Parent 3 - Children 1",
        "children": [{
            "id": 7,
            "name": "Parent 3 -> Children 1 -> Children 1"
          },
          {
            "id": 8,
            "name": "Parent 3 -> Children 1 -> Children 2"
          },
        ]
      }]
    }
  ]
}
<script src="https://unpkg.com/vue@2.6.10/dist/vue.js"></script>
<div id="app">
  <select v-model="selected">
    <option v-for="option in selectOptions" :value="option.id">{{ option.name }}</option>
  </select>
  <p>Selected: {{ selected }}</p>
</div>

Я использую вычисляемое свойство для удержания плоской версии дерева с небольшим количеством рекурсии для выравнивания.

0 голосов
/ 26 июня 2019

Вы можете загрузить параметры в свой mounted(), попробуйте что-то вроде этого:

mounted(){
  this.makeOptions();
},
methods: {
   makeOptions() {
      this.data.forEach( item => {
          this.opions.push({ value: item.id, label: item.name })
          if (item.children && item.children.length) {
              this.item.children.forEach(child => { 
                  this.opions.push({ value: child.id, label: child.name })
              })
          }
      })
   }

}

И вы можете зациклить свой шаблон через options. Удачи!

...