在 Vue 中为 JSON 数据创建下拉过滤器

Posted

技术标签:

【中文标题】在 Vue 中为 JSON 数据创建下拉过滤器【英文标题】:Creating a dropdown filter for JSON data in Vue 【发布时间】:2019-04-17 19:23:47 【问题描述】:

我想使用一个下拉列表来过滤我的 JSON 数据,并在它们与下拉选项匹配时显示不同的 JSON 数据项。到目前为止,我已经设法得到它,所以当有人从下拉菜单中选择一个项目时,一个函数就会运行,但我不确定为什么过滤器不起作用,因为我在控制台或 WebStorm 中没有收到任何错误.

这是我的代码和 JSON 数据的示例:

<template>
    <b-container id="product-list">
        <b-row>
            <b-col>
                <div>
                    <b-dropdown id="ddown4" text="Product Type" class="m-md-2">
                        <b-dropdown-item @click="FilterProducts" v-model="selectedCategory">4.5</b-dropdown-item>
                        <b-dropdown-item @click="FilterProducts" v-model="selectedCategory">10.5</b-dropdown-item>
                    </b-dropdown>
                </div>
            </b-col>
        </b-row>
        <hr>
        <b-row>
            <b-col md="4" v-for="product in Products">
                <img class="img-fluid" :src="product.image"/>
                <h5> product.product_name   </h5>
                <p class="original-price strikethrough">£ product.original_price </p>
                <p>£ product.final_price </p>
            </b-col>
        </b-row>
    </b-container>
</template>
<script>
    import Axios from "axios";

    export default 
        name: 'Products',
        data() 
            return 
                Products: null,
                selectedCategory: ''
            
        ,
        mounted() 
            Axios.get('/products.json')
                .then(response => (this.Products = response.data.data))
        ,
        methods: 
            FilterProducts() 
                var vm = this;
                var category = vm.selectedCategory;

                if(category === '') 
                    return vm.Products;
                 else 
                    return vm.Products.filter(function(product) 
                        return product.attributes.tog === category;
                    );
                
            
        
    
</script>

JSON 数据示例:

"data": [
    
      "id": "83",
      "product_name": "TV",
      "category": "Clearance",
      "original_price": "139.0000",
      "final_price": "105.0000",
      "attributes": 
        "size": "260x220",
        "tog": "10.5 tog"
      
      "url": "/tv"
    

【问题讨论】:

你为什么有两个&lt;b-dropdown-item @click="FilterProducts" v-model="selectedCategory"&gt;4.5&lt;/b-dropdown-item&gt; &lt;b-dropdown-item @click="FilterProducts" v-model="selectedCategory"&gt;10.5&lt;/b-dropdown-item&gt;下拉式投标selectedCategory 您还想显示过滤后的产品吗?您可能希望将 ` ` 替换为 &lt;b-col md="4" v-for="product in FilterProducts()"&gt; 是的,我想显示过滤后的产品,但即使进行了更新,它似乎也不起作用 【参考方案1】:

您的计算方法对selectedCategory 具有反应性,无需调用@click,因为您正在使用v-model

<template>
    <b-container id="product-list">
        <b-row>
            <b-col>
                <div>
                    <b-dropdown id="ddown4" text="Product Type" class="m-md-2">
                        <b-dropdown-item v-model="selectedCategory">4.5</b-dropdown-item>
                    </b-dropdown>
                </div>
            </b-col>
        </b-row>
        <hr>
        <b-row>
            <b-col md="4" v-for="product in filteredProducts">
                <img class="img-fluid" :src="product.image"/>
                <h5> product.product_name   </h5>
                <p class="original-price strikethrough">£ product.original_price </p>
                <p>£ product.final_price </p>
            </b-col>
        </b-row>
    </b-container>
</template>
<script>
    import Axios from "axios";

    export default 
        name: 'Products',
        data() 
            return 
                Products: null,
                selectedCategory: ''
            
        ,
        mounted() 
            Axios.get('/products.json')
                .then(response => (this.Products = response.data.data))
        ,
        computed: 
            filteredProducts() 

                if(this.selectedCategory === '') 
                    return this.Products;
                 else 
                    const category = this.selectedCategory;
                    return this.Products
                               .filter((product) => product.attributes.tog === category)
                
            
        
    
</script>

【讨论】:

确实运行没有错误,但显示的项目没有变化。即使您从下拉列表中选择一个选项,它们似乎都显示出来了。 更新:这个答案确实有效,我使用的是 Bootstrap-vue.js,而这个框架中的下拉菜单似乎不适用于此

以上是关于在 Vue 中为 JSON 数据创建下拉过滤器的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Angular 中为嵌套的 JSON 对象使用搜索过滤器?

如何在Vue中对对象数组进行排序和过滤

如何根据 JSON 数据和过滤参数过滤列表视图?

如何使用基于 JSON 的下拉菜单来过滤 xml 源?

如何为 bootstrap-vue 2.0 中的列创建动态输入过滤器

如何在 python 中为 pandas 创建一个“非”过滤器