Categories
Vuetify

Vuetify — Treeview Search and Open

Spread the love

Vuetify is a popular UI framework for Vue apps.

In this article, we’ll look at how to work with the Vuetify framework.

Open-All

Treeview nodes can be pre-opened on page load.

To do that, we can add the open-all prop to the v-treeview component:

<template>
  <v-treeview open-all :items="items"></v-treeview>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      {
        id: 1,
        name: "Root",
        children: [
          { id: 2, name: "Child 1" },
          { id: 3, name: "Child 2" },
          {
            id: 4,
            name: "Child 3",
            children: [
              { id: 5, name: "Grandchild 1" },
              { id: 6, name: "Grandchild 2" },
            ],
          },
        ],
      },
    ],
  }),
};
</script>

It’ll expand all the nodes when we load the page.

Treeview Slots

Treeviews have various slots.

The prepend slot lets us add content to the left of the node.

The label has the label for the node.

And the append slot lets us add content to the right of the label.

For example, we can write:

<template>
  <v-treeview v-model="tree" :open="open" :items="items" activatable item-key="name" open-on-click>
    <template v-slot:prepend="{ item, open }">
      <v-icon v-if="item.children">{{ open ? 'mdi-folder-open' : 'mdi-folder' }}</v-icon>
      <v-icon v-else>{{ item.id }}</v-icon>
    </template>
  </v-treeview>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    tree: undefined,
    open: ["Root"],
    items: [
      {
        id: 1,
        name: "Root",
        children: [
          { id: 2, name: "Child 1" },
          { id: 3, name: "Child 2" },
          {
            id: 4,
            name: "Child 3",
            children: [
              { id: 5, name: "Grandchild 1" },
              { id: 6, name: "Grandchild 2" },
            ],
          },
        ],
      },
    ],
  }),
};
</script>

to add a prepend slot so that we can show the nodes our way.

The slot has the item property with the node object.

And the open property is a boolean to indicate whether the node is open or not.

We can use them to display our nodes differently.

Searching Nodes

We can easily filter our treeview with the search prop.

The filtering can be customized.

For example, we can write:

<template>
  <v-card class="mx-auto" max-width="500">
    <v-sheet class="pa-4 primary lighten-2">
      <v-text-field
        v-model="search"
        label="Search"
        dark
        flat
        solo-inverted
        hide-details
        clearable
        clear-icon="mdi-close-circle-outline"
      ></v-text-field>
      <v-checkbox v-model="caseSensitive" dark hide-details label="Case sensitive search"></v-checkbox>
    </v-sheet>
    <v-card-text>
      <v-treeview :items="items" :search="search" :filter="filter" :open.sync="open"></v-treeview>
    </v-card-text>
  </v-card>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    open: [1, 2],
    search: null,
    caseSensitive: false,
    items: [
      {
        id: 1,
        name: "Root",
        children: [
          { id: 2, name: "Child 1" },
          { id: 3, name: "Child 2" },
          {
            id: 4,
            name: "Child 3",
            children: [
              { id: 5, name: "Grandchild 1" },
              { id: 6, name: "Grandchild 2" },
            ],
          },
        ],
      },
    ],
  }),
  computed: {
    filter() {
      return this.caseSensitive
        ? (item, search, textKey) => item[textKey].includes(search)
        : undefined;
    },
  },
};
</script>

We have the v-text-field to let us enter our search keyword.

The search state is passed into the search prop of the v-treeview to let us filter the items.

Also, we customize the search with the filter prop.

It returns a function that lets us return the condition that we want to match with the search.

Conclusion

We can add search to treeviews and also open all the nodes when the page loads.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *