1

I'm trying to create a vue js application where a treeview is displayed to the user. The elements inside the treeview can contain other elements, that can contain other elements etc ... With no limit, which means that the depth of the treeview is not known. If I'm right, it means I can't simply use the v-for directive (because it implies to know the depth right ?)

So i'm basically looping going through a json array and creating <ul> and <li> tags to append them to some other tag in the DOM, but if I do this, they don't get the styles of their class applied to them.

I suppose it's because Vue doesn't like the fact that we modify the DOM without having vue doing it for us.

Also, We don't want to use components libraries like vuetify, we want to do it with vue only and simple javascript.

Thank you !

7
  • This tree contains data about lessons that are available on the site. They are inside of categories that can contain subcategories that can themselves contain subcategories and so on ... I can know the depth of the tree only once I fetched it from my API, but in my vue component I can't predict it, so I can't use the v-for directive. But on a non-vue web page I could simply go iterate through the array recursively and build the tags consequently. The issue with this is that it implis to manipulate the DOM my self, and Vue does'nt like that Commented Mar 5, 2020 at 19:51
  • I see no reason why vue needs the depth before you request the data. Commented Mar 5, 2020 at 19:56
  • If you wan't to display a list of the things, you use v-for right ? But let's say the items in your list can also contain lists. Then you would put a 2nd v-for inside the first one. And the thing in my case, is that i don't know the depth of the tree. Right now it could be 3, but in 6months it could be ten. So I can't anticipate how many v-for i would have to imbricate. Commented Mar 5, 2020 at 20:00
  • you can nest components. Commented Mar 5, 2020 at 20:02
  • Yes I guessed it but wanted to know if there was an other way to do it. Thank you for your time :) Commented Mar 5, 2020 at 20:06

2 Answers 2

1

This is actually pretty straight forward in Vue.js.

What you have to do is simply create a component that invokes itself but changing the v-for to use the current tree branch's children.

An important step for making this work in Vue is to apply the name key to the component. Otherwise, the component can not invoke itself.

I have provided a simple example below using HTML's neat details element.

// Your recursive branch component "branch.vue"
const branch = {
  name: 'branch',
  props: {
    branch: {
      type: Object,
      default: () => ({}),
    },
  },
  template: `
    <details>
      <summary>{{ branch.title }}</summary>
      <branch
         v-for="branch in branch.children"
         :key="branch.title"
         :branch="branch"
       />
    </details>
  `,
}

// Your page view(component) where you want to display the tree
new Vue({
  el: '#app',
  name: 'tree',
  components: {
    branch,
  },
  data() {
    return {
      tree: [
        {
          title: 'parent 1',
          children: [
            {
              title: 'child 1',
              children: [
                {
                  title: 'child 1-1',
                  children: [],
                },
                {
                  title: 'child 1-2',
                  children: [],
                },
              ],
            },
          ],
        },
      ],
    };
  },
})
#app > details {
  margin-left: 0;
}
details {
  margin-left: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>

<div id="app">
  <branch v-for="branch in tree" :key="branch.title" :branch="branch" />
</div>

Sign up to request clarification or add additional context in comments.

Comments

0

The solution is to create a recursive component, for example see here and here

2 Comments

Yeah that's what i came up with, but I wanted to make sure there wasn't a better way to do it. Thank you for the link !
No Problem, You don't need to append the list in javascript part, you can simply import your current component in itself and use the component recursively with new props, and use a condition to put an end to this recursive component, like when no subcategory is in this item

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.