简体   繁体   中英

Vue JS 2: Bind computed property to data attribute

I have a data object in Vue.js 2 that looks like this:

data: {
     items: [
          {
            value1: 10, 
            value2: 10,
            valuesum: ""
          },
          {
            value1: 10, 
            value2: 100,
            valuesum: "",
          }
     ]

I render that data object in a table and run calculations on it. I want the valuesum property to be computed and stored in each object somehow. In other words, I want the code to essentially perform this:

data: {
     items: [
          {
            value1: 10, 
            value2: 10,
            valuesum: {{ value1 + value2 }} //20
          },
          {
            value1: 10, 
            value2: 100,
            valuesum: {{ value1 + value2 }} //110
          }
     ]

The computed attribute doesn't seem to be able to accomplish this. I tried to use the following function but this does not work:

 function (index) {
            for (let i = 0; i < this.items.length; i++ ){
                return this.items[index].value1 + this.items[index].value2;
            }
        }

The closest I have managed to get to an answer is by doing the calculation inline, but I can't bind its result to the items.total object. My HTML looks like this:

<table id="table">
        <thead>
            <tr>
                <td>Value 1</td>
                <td>Value 2</td>
                <td>Sum</td>
            </tr>
        </thead>
        <tbody>
            <tr v-for="item in items">
                <td><input type="number" v-model="item.value1"></td>
                <td><input type="number" v-model="item.value2"></td>
                <td> {{ item.value1 + item.value2 }} </td>
            </tr>
        </tbody>
    </table>

But I can't add v-model to it, since it's not an input. I'd like to avoid adding a readonly <input> to the column, since that doesn't seem like the best solution and isn't very elegant.

Here are a few approaches: Binding to a method, binding to a computed property, and binding to a data property that is saved during the computed property call:

  <table id="table">
     <thead>
        <tr>
           <td>Value 1</td>
           <td>Value 2</td>
           <td>Sum</td>
           <td>Sum</td>
           <td>Sum</td>
        </tr>
     </thead>
     <tbody>
        <tr v-for="(item, index) in items">
           <td><input type="number" v-model="item.value1"></td>
           <td><input type="number" v-model="item.value2"></td>
           <td> {{ sum(item) }} </td><!-- method -->
           <td> {{ sums[index] }}</td><!-- computed -->
           <td> {{ item.valuesum }}</td><!-- data property via computed -->
        </tr>
     </tbody>
  </table>

The script:

var vm = new Vue({
   el: "#table",
   data: function () {
      return {
         items: [
            {
               value1: 10, 
               value2: 10,
               valuesum: 0
            },{
               value1: 10, 
               value2: 100,
               valuesum: 0,
            }
         ]
      }
   },

   computed: {
      sums: function () {
         var val = [];
         for (var index in this.items) {
            var sum = this.sum(this.items[index]);
            val.push(sum);

            // Update the local data if you want
            this.items[index].valuesum = sum;
         }
         return val;
      }
   },

   methods: {
      sum: function (item) {
         // Alternate, if you take valuesum out:
         // for (var prop in item) {
         //    val += parseInt(item[prop]);
         // }
         return parseInt(item.value1) + parseInt(item.value2);
      }
   }
});

Is that the sort of thing you're looking for?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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