根据过滤结果展开v-treeview

时间:2019-06-04 11:21:13

标签: vuejs2 vuetify.js

在树状视图组件中,我想打开所有包含搜索文本的节点。但是预期没有实现。

所需的输出:在有一些搜索文本的地方打开所有父母。 enter image description here 这是相同的代码笔。

https://codepen.io/anon/pen/MdxPKN?&editors=101

<div id="app">
  <v-container grid-list-md>
    <v-layout wrap>
      <v-flex xs6>
        <v-text-field label="search" v-model="search" box />

        <v-treeview :items="tree"
          :search="search"
          active-class="grey lighten-4 indigo--text"
          item-key="name"
          open-on-click
          :open-all="{searchLength}>0?true:false"
          hoverable />
      </v-flex>
    </v-layout>
  </v-container>
</div>

3 个答案:

答案 0 :(得分:2)

这是一种基于您的示例的方法,可与内置搜索一起使用。

https://codepen.io/totalhack/pen/KKzzXvr

我添加了一个搜索输入事件处理程序,该处理程序使用treeview updateAll函数在搜索开始时打开所有项目。当搜索文本为空时,它然后返回到先前的open状态。请注意,如果您使用clearable的内置v-text-field道具,则可能也需要处理其中的事件(我没有尝试过)。

<div id="app">
  <v-app id="inspire">
    <v-container>
      <v-layout>
        <v-flex xs6>        
          <v-text-field
            label="Search"
            v-model="search"
            @input="handleSearch"
            >         
          </v-text-field>
          <v-treeview 
            ref="tree"
            :items="tree"
            :search="search"
            :open.sync="open"
            open-on-click
            hoverable>
          </v-treeview>
        </v-flex>
      </v-layout>
    </v-container>
  </v-app>
</div>
new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data(){
    return{
      search: '',
      open: [1],
      allOpened: false,
      lastOpen: [],
      tree: [
        {
          id: 1,
          name: 'Applications',
          children: [
            { id: 2, name: 'Calendar' },
            { id: 3, name: 'Chrome' },
            { id: 4, name: 'Webstorm' }
          ]
        },
        {
          id: 10,
          name: 'Languages',
          children: [
            { id: 20, name: 'English' },
            { id: 30, name: 'French' },
            { id: 40, name: 'Spannish' }
          ]
        }
        
      ]
    }
  },
  methods: {
    handleSearch: function (val) {
      if (val) {
        if (!this.allOpened) {
          this.lastOpen = this.open;
          this.allOpened = true;
          this.$refs.tree.updateAll(true);
        }
      } else {
        this.$refs.tree.updateAll(false);
        this.allOpened = false;
        this.open = this.lastOpen;
      }
    }
  }
})

答案 1 :(得分:1)

这有点棘手,您不能使用内置的搜索功能,但是有一个可以接受的简单解决方法。

基本上,您必须自己实现过滤器,然后将所需的项目发送到v-treeview

然后,您可以从filteredElements创建另一个计算属性,该属性仅返回key并将其传递给:open的{​​{1}}属性。

为您制作了一个Codepen。

https://codepen.io/brafols/pen/XwGQov

答案 2 :(得分:0)

我稍微修改了totalhack的解决方案,以得到我想要的。基本上,如果搜索框中有一个字符串,我将其称为updateAll(true)。

<template>
<v-card>
  <v-card-title>File Open</v-card-title>
  <v-sheet class="pl-4 pr-4">
    <v-text-field
      label="Search"
      v-model="search"
      @input="handleSearch"
      flat
      solo-inverted
      hide-details
      clearable
      clear-icon="mdi-close-circle-outline"
    ></v-text-field>
  </v-sheet>
  <v-card-text>
    <v-container>
      <v-treeview
        ref="tree"
        :items="tree"
        :search="search"
        open-on-click
        return-object
        activatable
        dense
      >
        <template v-slot:prepend="{ item, open }">
          <v-icon v-if="!item.file">
            {{ open ? 'mdi-folder-open' : 'mdi-folder' }}
          </v-icon>
          <v-icon v-else>
            {{ 'mdi-language-ruby' }}
          </v-icon>
        </template></v-treeview>
    </v-container>
  </v-card-text>
  <v-card-actions>
    <v-btn color="primary" text @click="open()">Ok</v-btn>
    <v-spacer></v-spacer>
    <v-btn color="primary" text @click="show = false">Cancel</v-btn>
  </v-card-actions>
</v-card>
</template>

<script>
export default {
  data() {
    return {
      tree: [],
      search: null,
    }
  },
  methods: {
    handleSearch(input) {
      if (input) {
        this.$refs.tree.updateAll(true)
      } else {
        this.$refs.tree.updateAll(false)
      }
    },
  },
}
</script>