每个计算属性的 Vue

Posted

技术标签:

【中文标题】每个计算属性的 Vue【英文标题】:Vue For Each Computed Property 【发布时间】:2018-09-20 13:48:42 【问题描述】:

这个问题可能有一个非常简单的解决方法,但我似乎无法让它正常工作。我正在使用 Vuetify 数据表循环显示我的所有属性,但是当我使用计算属性时它似乎无法正常工作。我正在尝试将一些道具(街道、城市、州、邮编)组合成一个计算的地址道具。因此,当我单独使用每个道具时,它可以像这样正常工作:

<td class="text-xs-center"> props.item.street </td>
<td class="text-xs-center"> props.item.city </td>
<td class="text-xs-center"> props.item.state </td>
<td class="text-xs-center"> props.item.zip </td>

但是,如果在我的 Vue 模板的脚本部分中,我会创建一个计算属性“fullAddress”,例如:

computed: 
  fullAddress () 
    return this.street & '\n' & this.city & ', ' & this.state & ' ' & this.zip
  

然后在上面的模板中使用它:

<td class="text-xs-center"> props.item.fullAddress() </td>

它根本不起作用。我还尝试了许多其他方法来写出来,但没有任何效果。我是 Vue 以及它如何使用计算属性的新手,所以我确信我只是不了解它是如何正常工作的。

编辑:我正在使用 Vuetify 数据表来遍历我的数据。我正在使用他们的文档来显示表格。就像我说的,我是 Vue 的新手,所以我试图弄清楚这一切。我相信 :items="items" 是所有道具的 v-bind(类似于 v-for 循环?)。下面是一个更完整的 Vuetify 对一个非常简单的数据表的例子:

<template>
  <v-data-table
    :headers="headers"
    :items="items"
    hide-actions
    class="elevation-1"
  >
    <template slot="items" slot-scope="props">
      <td> props.item.name </td>
      <td class="text-xs-right"> props.item.street </td>
      <td class="text-xs-right"> props.item.city </td>
      <td class="text-xs-right"> props.item.state </td>
      <td class="text-xs-right"> props.item.zip </td>
    </template>
  </v-data-table>
</template>

<script>
  export default 
    data () 
      return 
        headers: [
          
            text: 'Name',
            sortable: false,
            value: 'name'
          ,
           text: 'Street', value: 'street' ,
           text: 'City', value: 'city' ,
           text: 'State', value: 'state' ,
           text: 'Zip Code', value: 'zip' 
        ],
        items: [
          
            name: 'Braums',
            street: '159 W Elm St',
            city: 'St. Louis',
            state: 'MO',
            zip: 83607
          ,
          
            name: 'McDonalds',
            street: '237 N Cup Way',
            city: 'Dallas',
            state: 'TX',
            zip: 47621
          
        ]
      
    
  
</script>

【问题讨论】:

属性不是函数。 props.item.fullAddress() 是一个函数,请注意 ()。但是,您处于一个循环中,您无法获得单个属性来为您拥有的每个项目工作。为什么不直接使用 props.item.street props.item.city props.item.state 什么是props.item @RoyJ 对不起,我想这是相关信息。我有一个名为 items 的值数组。在表格中,我遍历了 props 中的项目,因此是 props.item.value。 @N.B.我确实尝试过,并且确实有效。我只是想学习如何让计算的属性工作。不必在每次需要输出地址时组合这些值,我想简单地调用该计算属性。 您可以采用几种方法,具体取决于数据结构和 html。我在那里推断出v-for,但props.item 符号不适用于它,所以我很困惑。您能否编辑问题以更全面地了解您正在使用的内容? 【参考方案1】:

感谢您扩展您的问题。

你不能做的:你不能有一个计算数组,因为计算不与数据项相关联,它们与组件相关联。按照您提出的编写方式,计算结果必须为每个item 提供不同的this。但它的this 是组件。

您可以创建一个基于items 的计算值,它返回items 中的每个值,并加上您为该项目计算的fullAddress 值。注意你要注意不要修改你原来的item;我使用Object.assign 创建一个新副本。

然后将计算数组传递给 v-table,而不是传递 items

我只是将新变量插入到 street 的位置以表明它有效。

Vue.use(Vuetify);

new Vue(
  el: '#app',
  data() 
    return 
      headers: [
          text: 'Name',
          sortable: false,
          value: 'name'
        ,
        
          text: 'Street',
          value: 'street'
        ,
        
          text: 'City',
          value: 'city'
        ,
        
          text: 'State',
          value: 'state'
        ,
        
          text: 'Zip Code',
          value: 'zip'
        
      ],
      items: [
          name: 'Braums',
          street: '159 W Elm St',
          city: 'St. Louis',
          state: 'MO',
          zip: 83607
        ,
        
          name: 'McDonalds',
          street: '237 N Cup Way',
          city: 'Dallas',
          state: 'TX',
          zip: 47621
        
      ]
    
  ,
  computed: 
    itemsWithFullAddress() 
      // This creates a new empty object, copies the item into it,
      // then calculates `fullAddress` and copies that entry into it
      return this.items.map((obj) => Object.assign(, obj, 
        fullAddress: `$obj.street\n$obj.city, $obj.state $obj.zip`
      ));
    
  
);
<link href="//unpkg.com/vuetify/dist/vuetify.min.css" rel="stylesheet" />
<script src="//unpkg.com/vue@latest/dist/vue.js"></script>
<script src="//unpkg.com/vuetify/dist/vuetify.min.js"></script>
<div id="app">
  <v-data-table :headers="headers" :items="itemsWithFullAddress" hide-actions class="elevation-1">
    <template slot="items" slot-scope="props">
      <td> props.item.name </td>
      <td class="text-xs-right"> props.item.fullAddress </td>
      <td class="text-xs-right"> props.item.city </td>
      <td class="text-xs-right"> props.item.state </td>
      <td class="text-xs-right"> props.item.zip </td>
    </template>
  </v-data-table>
</div>

【讨论】:

完美,效果很好!我将不得不研究您如何映射所有内容并使用 Object.assign 但这至少可以帮助我朝着正确的方向前进!谢谢你的帮助!您能否简要解释一下为什么不能像我尝试使用它那样使用计算属性? 我为此添加了一段。我希望它会有所帮助。我觉得很难解释清楚。

以上是关于每个计算属性的 Vue的主要内容,如果未能解决你的问题,请参考以下文章

Vue计算属性和监听属性

Vue 计算属性改变存储状态

Vue源码之计算属性watcher

Vue源码之计算属性watcher

vue的watch、methods 和 computed 的区别

vue2源码-- computed 计算属性的实现