Vue v-for 循环 - 过滤数组时如何定位组件

Posted

技术标签:

【中文标题】Vue v-for 循环 - 过滤数组时如何定位组件【英文标题】:Vue v-for loop - How To Target Component When Array is Filtered 【发布时间】:2019-04-29 17:33:57 【问题描述】:

我正在使用计算值来动态过滤数组(“订单”)。

计算出的.filter() 函数允许用户按订单号、名称或参考号动态搜索:

data() 
  return 
    orders: [],
    search: ""  // search string from a text input    
  ;
,

computed: 
  filtered: 
    return this.orders.filter(order => 
      const s =
        order.order_number + order.reference + order.name;
      const su = s.toUpperCase();
      return su.match(this.search.toUpperCase());
    );
  

我正在使用v-for 循环来呈现搜索结果,如下所示:

 <tbody v-for="(order, index) in filtered" :key="order.id">              
   <tr>       
     <td @click="add_events(order, index)>order.order_number</td>
     <td>order.reference</td>
     <td>order.name</td>
      ...
    </tr>
  </tbody>

我想使用@click 来定位过滤数组中的特定组件(对象)并使用$set 将值(“objEvents”)附加到该对象:

methods: 
  add_events (order, index) 
    const objEvents= [ external data from an API ]      
    this.$set(this.orders[index], "events", objEvents)          
  

但是,filtered 数组(“filtered”)中组件的indexoriginal 数组(“orders”中的index 不同") 等add_events 方法针对错误的组件。

我可以使用key 来定位正确的组件吗?还是有其他方法可以识别过滤数组中的目标组件?

【问题讨论】:

【参考方案1】:

无需跟踪indexfiltered 只是orders对原始对象的引用 的数组,因此您可以修改add_events() 中的order 迭代器以达到预期的效果:

this.$set(order, 'events', objEvents);

new Vue(
  el: '#app',
  data() 
    return 
      orders: [
        id: 1, order_number: 111, name: 'John', reference: 'R111',
        id: 2, order_number: 222, name: 'Bob', reference: 'R222',
        id: 3, order_number: 333, name: 'Bob', reference: 'R333',
      ],
      search: ''
    ;
  ,
  computed: 
    filtered() 
      return this.orders.filter(order => 
        const s =
              order.order_number + order.reference + order.name;
        const su = s.toUpperCase();
        return su.match(this.search.toUpperCase());
      );
    
  ,
  methods: 
    add_events(order, index) 
      const objEvents = [
        id: 1, name: 'Event 1',
        id: 2, name: 'Event 2',
        id: 3, name: 'Event 3'
      ];
      this.$set(order, "events", objEvents);
    
  
)
<script src="https://unpkg.com/vue@2.5.17"></script>

<div id="app">
  <input type="text" v-model="search" placeholder="Search">
  <table>
    <tbody v-for="(order, index) in filtered" :key="order.id">              
      <tr>
        <td @click="add_events(order, index)">order.order_number</td>
        <td>order.reference</td>
        <td>order.name</td>
        <td>order.events</td>
      </tr>
    </tbody>
  </table>
  
  <pre>orders</pre>
</div>

【讨论】:

【参考方案2】:

您可以映射原始数组并将origIndex 属性添加到每个项目,如下所示:

    computed:
        filtered()
           let mapped= this.orders.map((item,i)=>
                             let tmp=item;
                              tmp.origIndex=i;
                             return tmp;
                            );
             return this.mapped.filter(order => 
                    const s =
                      order.order_number + order.reference + order.name;
                       const su = s.toUpperCase();
                    return su.match(this.search.toUpperCase());
             );
            
        //end computed

在您的模板中使用origIndex 属性而不是index

           <tbody v-for="(order, index) in filtered" :key="order.id">              
              <tr>       
                <td @click="add_events(order, order.origIndex)>order.order_number</td>
               <td>order.reference</td>
                <td>order.name</td>
                 ...
               </tr>
            </tbody>

【讨论】:

这行得通 - 谢谢。但我曾希望有某种方法可以选择 Vue 内部使用的 key 字段来定位单个组件。 @AlexWebster 对不起,我可能误解了你的用例 不 - 我认为您完全理解我的问题,但我走错了路。 @tony19 接受的回答表明,实际上并不需要 index 。再次感谢。

以上是关于Vue v-for 循环 - 过滤数组时如何定位组件的主要内容,如果未能解决你的问题,请参考以下文章

第十节:Vue指令:v-for列表循环

第十节:Vue指令:v-for列表循环

在 keyup 上过滤数组结果

Vue.js v-for 循环绑定数组中的项目对象并在更改时更新

vue里面如何让v-for循环出来的列表里面的列表跳转到不同的页面?

Vue.js列表渲染 v-for