【问题标题】:Add search and sort functionality to VuetifyJS list with VueJS 2使用 VueJS 2 向 VuetifyJS 列表添加搜索和排序功能
【发布时间】:2019-01-26 12:08:26
【问题描述】:

我需要向VuetifyJS list 添加一个简单的搜索和排序功能。 这是列表的 CodePen 示例:https://codepen.io/anon/pen/bxGGgv

在 VueJS 2 中执行此操作的标准方法是什么?

HTML:

<v-list two-line>
  <template v-for="(item, index) in items">
      <v-list-tile
        :key="item.title"
        avatar
        ripple
        @click="toggle(index)"
      >
        <v-list-tile-content>
           <v-list-tile-title>{{ item.title }}</v-list-tile-title>
           <v-list-tile-sub-title class="text--primary">
               {{ item.headline }}
           </v-list-tile-sub-title>
           <v-list-tile-sub-title>{{ item.subtitle }}</v-list-tile-sub-title>
        </v-list-tile-content>
      </v-list-tile>
      <v-divider
        v-if="index + 1 < items.length"
        :key="index"
      ></v-divider>
  </template>
</v-list>

JS:

  export default {
    data () {
      return {
        selected: [2],
        items: [
          {
            action: '15 min',
            headline: 'Brunch this weekend?',
            title: 'Ali Connors',
            subtitle: "I'll be in your neighborhood doing errands this weekend. Do you want to hang out?"
          },
          {
            action: '18hr',
            headline: 'Recipe to try',
            title: 'Britta Holt',
            subtitle: 'We should eat this: Grate, Squash, Corn, and tomatillo Tacos.'
          }
        ]
      }
    },
  }

【问题讨论】:

    标签: javascript search vue.js vuejs2 vuetify.js


    【解决方案1】:

    你可以在你的类中定义一个计算属性并做你的过滤器。您可以将此计算属性用作您的 filteringsorting 功能。

    这里是codepen

    new Vue({
        el: '#app',
        data: {
            selected: [2],
            search: '',
            items: [{
                    action: '15 min',
                    headline: 'Brunch this weekend?',
                    title: 'Ali Connors',
                    subtitle: "I'll be in your neighborhood doing errands this weekend. Do you want to hang out?"
                },
                {
                    action: '2 hr',
                    headline: 'Summer BBQ',
                    title: 'me, Scrott, Jennifer',
                    subtitle: "Wish I could come, but I'm out of town this weekend."
                },
                {
                    action: '6 hr',
                    headline: 'Oui oui',
                    title: 'Sandra Adams',
                    subtitle: 'Do you have Paris recommendations? Have you ever been?'
                },
                {
                    action: '12 hr',
                    headline: 'Birthday gift',
                    title: 'Trevor Hansen',
                    subtitle: 'Have any ideas about what we should get Heidi for her birthday?'
                },
                {
                    action: '18hr',
                    headline: 'Recipe to try',
                    title: 'Britta Holt',
                    subtitle: 'We should eat this: Grate, Squash, Corn, and tomatillo Tacos.'
                }
            ]
        },
        computed: {
            filteredItems() {
                return _.orderBy(this.items.filter(item => {
                    return item.title.toLowerCase().includes(this.search.toLowerCase()) ||
                        item.action.toLowerCase().includes(this.search.toLowerCase()) ||
                        item.headline.toLowerCase().includes(this.search.toLowerCase()) ||
                        item.subtitle.toLowerCase().includes(this.search.toLowerCase());
                }), 'headline');
            }
        },
        methods: {
            toggle(index) {
                const i = this.selected.indexOf(index)
    
                if (i > -1) {
                    this.selected.splice(i, 1)
                } else {
                    this.selected.push(index)
                }
            }
        }
    })
    

    【讨论】:

    • 谢谢,但 | orderBy 'title' 在 VueJS 2 中似乎不再适用。你会为 VueJS 2 推荐什么?
    • 是的。你说得对。我几乎忘记了。您应该使用 loadash (_) 在您的计算属性中排序您的列表。而且你应该从你的模板中删除| orderBy 'title'。像这样的东西:return _.orderBy(item.title.includes(this.search), 'title')
    • 谢谢,效果很好,但是如何通过按钮重置搜索?我用文本字段的 clearable 选项更新了您的示例笔:codepen.io/anon/pen/wEaBzX单击后如何显示所有条目?
    • 您应该手动处理清除按钮事件。我已经编辑了我的example
    【解决方案2】:

    这可能不是标准方式,但您也可以这样尝试...

    首先通过添加 v-model search 和数组 searchItem 来过滤搜索中的输入。您还需要在 mounted 挂钩中初始化 searchItem。然后创建一个计算属性filteredItems。如果您将使用正则表达式并且它返回一个数组,我已经使用.filter().match() 以获得灵活性。

    但你也可以使用.includes() 这取决于你的选择

    HTML(更改)

    <v-toolbar>
       <v-text-field
         v-model="search" //add this
         ...
       ></v-text-field>
    </v-toolbar>
    
    <v-list two-line>
      <template v-for="(item, index) in filteredItems"> //change items to filteredItems
       ...
      </template>
    </v-list>
    

    JS:

    data () {
      return {
        search: '',
        selected: [2],
        searchItem: [],
        items: [
           // your items here
        ]
      }
    },
    
    mounted() {
      setTimeout(() => this.searchItem = this.items)
    },
    
    computed: {
     filteredItems() {
        return this.searchItem.filter((item) =>{
             return item.title.toLowerCase().match(this.search)  || 
                    item.headline.toLowerCase().match(this.search) || 
                    item.subtitle.toLowerCase().match(this.search) || 
                    item.action.toLowerCase().match(this.search)
        })
      }
    }
    

    演示:

    您更新的 Codepen here

    【讨论】:

    • 谢谢,但我收到此错误:箭头函数不应返回赋值setTimeout(() =&gt; this.searchItem = this.items) 需要更改什么?
    • 你可以使用普通的 setTimeout() 函数或者让它成为this.searchItem = this.items
    • 你检查过codepen吗?即使我在我的电脑上尝试过,它也能正常工作。
    • 我猜是因为我的设置中的 "babel-eslint": "^8.0.1" 或 "eslint": "^4.9.0" ?
    猜你喜欢
    • 2017-11-13
    • 1970-01-01
    • 1970-01-01
    • 2017-09-02
    • 2016-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多