使用 VueJS 进行复选框过滤 [英] Checkbox filtering with VueJS

查看:28
本文介绍了使用 VueJS 进行复选框过滤的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的第一个 VueJS 项目(从 jQuery 迁移),我正在尝试过滤带有多个复选框的网格.正如您从 JavaScript 中看到的,我有一个 filterJobs 函数,它使用从检查的内容(v-model="checkedLocations")设置的值过滤数组.array.includes 似乎过滤单个值,我想过滤多个值.我不想弹出或切片数组,因为如果他们取消选中某个位置,他们就会消失并且不会重新绑定

让职业生涯 = 职业生涯 ||{};职业生涯.taleo =(函数($){让应用程序;让 init = 函数(){应用程序 = 新的 Vue({el: '#app',数据: {地点:['亚利桑那州斯科茨代尔'、'亚利桑那州钱德勒'、'加利福尼亚州欧文'、'科罗拉多州丹佛'、'伊利诺伊州芝加哥'、'马里兰州罗克维尔'、'密苏里州堪萨斯城'、'北卡罗来纳州夏洛特市','Red Bank, NJ','Henderson, NV','Melville, NY','Allentown, PA','Irving, TX'],工作:空,已检查地点:[]},创建:函数(){this.fetchData();},方法: {fetchData: 函数 () {this.jobs = [{ id: '1', title: 'Circuit Court Clerk', description: 'lorem ipsum', location: 'Charlotte, NC', 部门:'Sales and Marketing',日期:'23/10/17' },{ id: '2', title: 'Tie Buyer', 描述: 'lorem ipsum', location: 'Irvine, CA', 部门: 'Media Relations', date: '21/10/16' },{ id: '3', title: 'Leaded Glass Installer', description: 'lorem ipsum', location: 'Kansas City, MO', 部门: 'Public Relations', date: '16/09/17' },{ id: '4', title: 'Wheat Inspector', description: 'lorem ipsum', location: 'Red Bank, NJ', 部门: 'Quality Assurance', 日期: '12/06/16' },{ id: '5', title: 'Executive Officer, Special Warfare Team', description: 'lorem ipsum', location: 'Irving, TX', 部门:'Public Relations',日期:'19/03/18' },{ id: '6', title: 'Wildlife Control Agent', description: 'lorem ipsum', location: 'Irvine, CA', 部门: 'Sales and Marketing', date: '07/01/17' },{ id: '7', title: 'Arresting Gear Operator', 描述: 'lorem ipsum', location: 'Charlotte, NC', 部门: 'Asset Management', 日期: '04/09/17' },{ ID:'8',标题:'逮捕齿轮操作员',描述:'lorem ipsum',位置:'Chandler,AZ',部门:'技术支持',日期:'01/04/17'},{ id: '9', title: 'Biogeographer', description: 'lorem ipsum', location: 'Chicago, IL', 部门: 'Quality Assurance', 日期: '01/05/17' },{ id:'10',标题:'LAN 系统管理员',描述:'lorem ipsum',位置:'亚利桑那州斯科茨代尔',部门:'客户关系',日期:'29/04/18'},{ id:'11',标题:'Copper Plater',描述:'lorem ipsum',位置:'Irving,TX',部门:'技术支持',日期:'17/08/17'},{ id: '12', title: 'Leaded Glass Installer', description: 'lorem ipsum', location: 'Rockville, MD', 部门: 'Sales and Marketing', date: '02/11/16' },{ id:'13',标题:'Line Cook',描述:'lorem ipsum',位置:'Chandler,AZ',部门:'广告',日期:'02/12/17'},{ id: '14', title: 'Special Education Teaching Assistant', description: 'lorem ipsum', location: 'Red Bank, NJ', 部门: 'Payroll', 日期: '02/05/17' },{ id: '15', title: 'Clarinetist', description: 'lorem ipsum', location: 'Melville, NY', 部门: 'Payroll', 日期: '30/05/17' },{ id: '16', title: 'Arresting Gear Operator', 描述: 'lorem ipsum', location: 'Henderson, NV', 部门: 'Payroll', 日期: '23/02/18' },{ id: '17', title: 'Wheat Inspector', description: 'lorem ipsum', location: 'Red Bank, NJ', 部门: 'Tech Support', date: '12/08/16' },{ id: '18', title: 'Wildlife Control Agent', description: 'lorem ipsum', location: 'Melville, NY', 部门: 'Payroll', 日期: '03/05/17' },{ id: '19', title: 'Print Retoucher', description: 'lorem ipsum', location: 'Chicago, IL', 部门: 'Sales and Marketing', date: '19/06/16' },{ ID:'20',标题:'数学统计学家',描述:'lorem ipsum',位置:'亚利桑那州斯科茨代尔',部门:'技术支持',日期:'10/07/16'}];},filterJobs:函数(事件){app.jobs = app.jobs.filter(function (job) {返回 job.location.includes(app.checkedLocations);});//filterJobs: function(event) {//app.jobs = app.jobs.filter( function( location ) {//返回 !app.checkedLocations.includes( location );//} );}}});};返回{初始化,应用};})();(功能(){职业生涯.taleo.init();})();

#app {填充:25px;}#app ul {左边距:0;填充:0;}#app ul li {列表样式:无;}

<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="样式表"/><script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.min.js"></script><div id="应用程序"><div class="container-fluid"><div class="row"><div class="col-md-3"><h3>位置</h3><ul><li v-for="location in location"><input type="checkbox" v-model="checkedLocations" v-on:click="filterJobs" v-bind:value="location"/>{{地点}}<span>检查的位置:{{ checkedLocations }}</span>

<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">{{ 职称 }}<small class="pull-right text-muted" style="font-size: 12x">{{job.date}}</小><p class="card-text"><!-- {{job.description}} --></p><button class="btn btn-sm btn-primary">查看</button>

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

解决方案

对过滤的位置使用计算值.

计算:{过滤作业(){//如果没有选中的位置,则返回所有内容.//如果你只想返回,你可以删除它//检查位置.如果(!this.checkedLocations.length)返回 this.jobs返回 this.jobs.filter(j => this.checkedLocations.includes(j.location))}}

并修改您的模板.

同时删除您的 filterJobs 方法.

示例.

基本上你需要将过滤器翻转到

this.checkedLocations.includes(job.location).

此外,您不希望每次过滤时都更改数据,因为您正在流失数据.然而,使用计算值对于 Vue 来说更为惯用.

This is my first VueJS project (making the move from jQuery) and I am trying to filter a grid with multiple checkboxes. 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"). array.includes appears to filter on a single value and I'd like to filter multiple values. 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

解决方案

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.

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.

这篇关于使用 VueJS 进行复选框过滤的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆