简体   繁体   English

使用VueJS过滤复选框

[英]Checkbox filtering with VueJS

This is my first VueJS project (making the move from jQuery) and I am trying to filter a grid with multiple checkboxes. 这是我的第一个VueJS项目(从jQuery转移),我正在尝试使用多个复选框过滤网格。 As you can see from the JavaScript, I have a filterJobs function that filters the array with values set from whats checked (the v-model="checkedLocations"). 正如您在JavaScript中看到的,我有一个filterJobs函数,它使用从whats选中设置的值来过滤数组(v-model =“checkedLocations”)。 array.includes appears to filter on a single value and I'd like to filter multiple values. array.includes似乎过滤单个值,我想过滤多个值。 I don't want to pop or slice the array because if they uncheck a location the they'll be gone and won't rebind 我不想弹出或切片数组,因为如果他们取消选中一个位置,它们就会消失并且不会重新绑定

 let careers = careers || {}; careers.taleo = (function($){ let app; let init = function() { app = new Vue({ el: '#app', data: { locations: ['Scottsdale, AZ','Chandler, AZ','Irvine, CA','Denver, CO','Chicago, IL','Rockville, MD','Kansas City, MO','Charlotte, NC','Red Bank, NJ','Henderson, NV','Melville, NY','Allentown, PA','Irving, TX'], jobs: null, checkedLocations: [] }, created: function () { this.fetchData(); }, methods: { fetchData: function () { this.jobs = [ { id: '1', title: 'Circuit Court Clerk', description: 'lorem ipsum', location: 'Charlotte, NC', department: 'Sales and Marketing', date: '23/10/17' }, { id: '2', title: 'Tie Buyer', description: 'lorem ipsum', location: 'Irvine, CA', department: 'Media Relations', date: '21/10/16' }, { id: '3', title: 'Leaded Glass Installer', description: 'lorem ipsum', location: 'Kansas City, MO', department: 'Public Relations', date: '16/09/17' }, { id: '4', title: 'Wheat Inspector', description: 'lorem ipsum', location: 'Red Bank, NJ', department: 'Quality Assurance', date: '12/06/16' }, { id: '5', title: 'Executive Officer, Special Warfare Team', description: 'lorem ipsum', location: 'Irving, TX', department: 'Public Relations', date: '19/03/18' }, { id: '6', title: 'Wildlife Control Agent', description: 'lorem ipsum', location: 'Irvine, CA', department: 'Sales and Marketing', date: '07/01/17' }, { id: '7', title: 'Arresting Gear Operator', description: 'lorem ipsum', location: 'Charlotte, NC', department: 'Asset Management', date: '04/09/17' }, { id: '8', title: 'Arresting Gear Operator', description: 'lorem ipsum', location: 'Chandler, AZ', department: 'Tech Support', date: '01/04/17' }, { id: '9', title: 'Biogeographer', description: 'lorem ipsum', location: 'Chicago, IL', department: 'Quality Assurance', date: '01/05/17' }, { id: '10', title: 'LAN Systems Administrator', description: 'lorem ipsum', location: 'Scottsdale, AZ', department: 'Customer Relations', date: '29/04/18' }, { id: '11', title: 'Copper Plater', description: 'lorem ipsum', location: 'Irving, TX', department: 'Tech Support', date: '17/08/17' }, { id: '12', title: 'Leaded Glass Installer', description: 'lorem ipsum', location: 'Rockville, MD', department: 'Sales and Marketing', date: '02/11/16' }, { id: '13', title: 'Line Cook', description: 'lorem ipsum', location: 'Chandler, AZ', department: 'Advertising', date: '02/12/17' }, { id: '14', title: 'Special Education Teaching Assistant', description: 'lorem ipsum', location: 'Red Bank, NJ', department: 'Payroll', date: '02/05/17' }, { id: '15', title: 'Clarinetist', description: 'lorem ipsum', location: 'Melville, NY', department: 'Payroll', date: '30/05/17' }, { id: '16', title: 'Arresting Gear Operator', description: 'lorem ipsum', location: 'Henderson, NV', department: 'Payroll', date: '23/02/18' }, { id: '17', title: 'Wheat Inspector', description: 'lorem ipsum', location: 'Red Bank, NJ', department: 'Tech Support', date: '12/08/16' }, { id: '18', title: 'Wildlife Control Agent', description: 'lorem ipsum', location: 'Melville, NY', department: 'Payroll', date: '03/05/17' }, { id: '19', title: 'Print Retoucher', description: 'lorem ipsum', location: 'Chicago, IL', department: 'Sales and Marketing', date: '19/06/16' }, { id: '20', title: 'Mathematical Statistician', description: 'lorem ipsum', location: 'Scottsdale, AZ', department: 'Tech Support', date: '10/07/16' } ]; }, filterJobs: function(event) { app.jobs = app.jobs.filter(function (job) { return job.location.includes(app.checkedLocations); }); // filterJobs: function(event) { // app.jobs = app.jobs.filter( function( location ) { // return !app.checkedLocations.includes( location ); // } ); } } }); }; return { init, app }; })(); (function(){ careers.taleo.init(); })(); 
 #app { padding: 25px; } #app ul { margin-left: 0; padding: 0; } #app ul li { list-style: none; } 
 <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.min.js"></script> <div id="app"> <div class="container-fluid"> <div class="row"> <div class="col-md-3"> <h3>Locations</h3> <ul> <li v-for="location in locations"> <input type="checkbox" v-model="checkedLocations" v-on:click="filterJobs" v-bind:value="location" /> {{location}} </li> </ul> <span>Checked locations: {{ checkedLocations }}</span> </div> <div class="col-md-9"> <div class="jobs"> <div class="job" v-for="job in jobs"> <div class="card" style="margin: 5px 0"> <div class="card-block"> <h4 class="card-title"> {{ job.title }} </h4> <small class="pull-right text-muted" style="font-size: 12x"> {{job.date}} </small> <p class="card-text"> <!-- {{job.description}} --> </p> <button class="btn btn-sm btn-primary">View</button> </div> </div> </div> </div> </div> </div> </div> </div> 

https://codepen.io/neil/pen/WjXrxx https://codepen.io/neil/pen/WjXrxx

Use a computed value for your filtered locations. 为过滤的位置使用计算值。

computed:{
  filteredJobs(){
    // if there are no checked locations, return everything.
    // You could remove this if you only want to return 
    // checked locations.
    if (!this.checkedLocations.length)
       return this.jobs

     return this.jobs.filter(j => this.checkedLocations.includes(j.location))
  }
}

And modify your template. 并修改您的模板。

<div class="job" v-for="job in filteredJobs">

While also removing your filterJobs method. 同时还删除了您的filterJobs方法。

Example . 例子

Basically you needed to flip your filter to 基本上你需要翻转你的过滤器

this.checkedLocations.includes(job.location). 

Also, you don't want to be changing your data every time you filter because you are bleeding data. 此外,您不希望每次过滤时都更改数据,因为您正在排除数据。 Using a computed value is more idiomatic for Vue however. 然而,对于Vue,使用计算值更惯用。

Use v-if in line where you list jobs: 在列出作业的位置使用v-if:

<div class="job" v-if=filterJobs(job) v-for="job in jobs">

and use method filterJobs like that: 并使用像这样的方法filterJobs:

filterJobs: function(data) {
        if (this.checkedLocations.length == 0) return true;
        return this.checkedLocations.includes(data.location);
}

Edited code 编辑过的代码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM