【问题标题】:Issue when using Vuejs with computed filter使用带有计算过滤器的 Vuejs 时出现问题
【发布时间】:2017-04-19 18:37:37
【问题描述】:

我正在使用带有复选框的 Vuejs 编写过滤器应用程序。当我使用单个复选框时效果很好。但是,当我选中超过 2 个复选框时,它会删除结果。

例如,当我检查绿色和红色时,它应该显示标题 1 和标题 2。 或者当我检查绿色、红色、活动、已完成时,它应该显示标题 1 和标题 2。

您可以查看我的代码:https://jsfiddle.net/dalenguyen/xLcvdy0n/1/

HTML 代码:

<div class="content">
<div class="row">
    <div class="col-md-3 col-sm-4">
        <div class="box box-info">
            <div class="box-header with-border">
                <h3 class="box-title">Filter by</h3>
            </div>
            <!-- /.box-header -->
            <!-- form start -->
                <div class="box-body">
                    <div class="box box-success box-solid">
                        <div class="box-header with-border">
                            <h3 class="box-title">Health</h3>
                            <!-- /.box-tools -->
                        </div>
                        <!-- /.box-header -->
                        <div class="box-body" style="display: block;">
                            <div class="form-group col-md-12">
                                <input type="checkbox" id="green" value="Green" v-model="checkedHealths" name="Healths">
                                <label for="green">Green</label>

                            </div>
                            <div class="form-group col-md-12">
                                <input type="checkbox" id="red" value="Red" v-model="checkedHealths" name="Healths">
                                <label for="red">Red</label>
                            </div>
                            <div class="form-group col-md-12">
                                <input type="checkbox" id="yellow" value="Yellow" v-model="checkedHealths" name="Healths">
                                <label for="yellow">Yellow</label>
                            </div>
                        </div>
                        <!-- /.box-body -->                      
                    </div>

                    <div class="box box-success box-solid">
                        <div class="box-header with-border">
                            <h3 class="box-title">Status</h3>
                            <!-- /.box-tools -->
                        </div>
                        <!-- /.box-header -->
                        <div class="box-body" style="display: block;">
                            <div class="form-group col-md-12">
                                <input type="checkbox" id="active" value="Active" v-model="checkedStatuses" name="Statuses">
                                <label for="active">Active</label>
                            </div>
                            <div class="form-group col-md-12">
                                <input type="checkbox" id="completed" value="Completed" v-model="checkedStatuses" name="Statuses">
                                <label for="completed">Completed</label>
                            </div>
                            <div class="form-group col-md-12">
                                <input type="checkbox" id="cancelled" value="Cancelled" v-model="checkedStatuses" name="Statuses">
                                <label for="cancelled">Cancelled</label>
                            </div>
                        </div>
                        <!-- /.box-body -->
                    </div>
                    <button type="button" class="btn btn-block btn-info" v-on:click="resetFilter">Reset</button>

                </div>
                <!-- /.box-body -->
        </div>
    </div>
    <div class="col-md-9 col-sm-8">

        <div class="col-md-4" v-for="project in filteredProjects">
            <div class="box collapsed-box">
                <div class="box-header with-border">
                    <h4 class="box-title"><a href="">{{project['title']}}</a></h4>
                    <!-- /.box-tools -->
                </div>
                <!-- /.box-header -->
                <div class="box-body">
                    <table class="table table-striped">
                        <tr>
                            <td>Status</td>
                            <td>{{project['Status']}}</td>
                        </tr>
                         <tr>
                            <td>Health</td>
                            <td>{{project['Health']}}</td>
                        </tr>
                    </table>
                </div>
                <!-- /.box-body -->
            </div>
            <!-- /.box -->
        </div>
    </div>
</div>

</div>

Vuejs 代码:

var app = new Vue({
            el: '.content',

            data: {
                projects: [
                    {
                      "title": "Title 1",
                      "Status": "Active",
                      "Health": "Green",
                    },
                    {
                      "title": "Title 2",
                      "Status": "Completed",
                      "Health": "Red",
                    },
                    {
                      "title": "Title 3",
                      "Status": "Cancelled",
                      "Health": "Yellow",
                    },                    
                  ]                                
                ,
                checkedHealths: [],
                checkedStatuses: []
            },

            computed: {
                filteredProjects: function(){
                    let filterProjects = this.projects;


                    $.each(this.checkedHealths, function(value, key){                       
                       filterProjects = filterProjects.filter(function(project){                            
                           return project.Health == key;
                       })
                    });

                    $.each(this.checkedStatuses, function(value, key){
                        filterProjects = filterProjects.filter(function(project){
                            return project.Status.includes(key);
                        })
                    });

                    return filterProjects;
                }
            },

            mounted: function(){

                jQuery('input').iCheck({
                    checkboxClass: 'icheckbox_square-green',
                    radioClass: 'iradio_square-green',
                    increaseArea: '20%' // optional
                });

                jQuery('input').on('ifChecked', function(e){

                    if($(this).attr('name') === "Healths")
                        app.$data.checkedHealths.push($(this).val());

                    if($(this).attr('name') === "Statuses")
                        app.$data.checkedStatuses.push($(this).val());

                });

                jQuery('input').on('ifUnchecked', function(e){

                    if($(this).attr('name') === "Healths"){
                        let data = app.$data.checkedHealths;
                        app.$data.checkedHealths.splice(data.indexOf($(this).val()),1);
                    }

                    if($(this).attr('name') === "Statuses"){
                        let data = app.$data.checkedStatuses;
                        app.$data.checkedStatuses.splice(data.indexOf($(this).val()),1);
                    }

                });
            },

            methods: {
                resetFilter: function(){
                    $('input').iCheck('uncheck');
                }
            }
        })

【问题讨论】:

    标签: javascript jquery vuejs2


    【解决方案1】:

    您的filterProjects 方法应该如下所示。

    filteredProjects: function(){
      let filterProjects = this.projects;
    
      if (this.checkedHealths.length > 0){
        filterProjects = filterProjects.filter(project => {
          return this.checkedHealths.includes(project.Health);
        })
      }
    
      if (this.checkedStatuses.length > 0){
        filterProjects = filterProjects.filter(project => {
          return this.checkedStatuses.includes(project.Status)
        })
      }
    
      return filterProjects;
    }
    

    更新fiddle

    基本上,您的旧过滤器代码是单独检查每个过滤器,您需要一次处理所有过滤器。上面的代码循环遍历项目并检查项目的值是否在选定的过滤器值中。

    您还使用了很多 jQuery,而您可能只是使用本机方法和 Vue。

    【讨论】:

    • 感谢@Bert Evans。你太棒了!
    • 因为iCheck需要JQuery,所以我用它。您可以推荐任何最佳实践吗?谢谢,
    • @DaleNguyen 通常,对于 jQuery 插件,您希望将它们包装在 Vue 组件中。在这种情况下,您可能想要创建一个 iCheck 复选框组件,并且任何 jQuery 代码都只能在其中使用。这是包装插件的 Vue 文档中的一个示例。 vuejs.org/v2/examples/select2.html
    • @DaleNguyen 这是一个简单的示例,说明如何为 iCheck 做一个。它不会像你的小提琴那样工作,但这是一种方法。 codepen.io/Kradek/pen/OmMvEJ?editors=1010
    • 非常感谢。我会研究一下,以使我的代码更好。
    猜你喜欢
    • 1970-01-01
    • 2016-07-08
    • 1970-01-01
    • 2022-01-09
    • 2011-03-06
    • 2020-01-23
    • 2020-10-21
    • 2015-05-01
    • 2023-03-15
    相关资源
    最近更新 更多