最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Vue.js - How to implement Computed properties on objects of array? - Stack Overflow

programmeradmin3浏览0评论

I have an array of objects inside my Vue instance, and for each item I'd like to write a Computed property.

Each object has only two properties: firstName and lastName. I would like to write a Computed property for each named 'fullName', which is just a concatenation of firstName and lastName.

I'm familiar with implementing Computed properties of data object properties of a Vue instances, but when it es to doing so with elements of an array, I get confused.

Currently, my code is this:

var app = new Vue({
  el: '#app',
  data: {
    names: [{
        firstName: 'Mike',
        lastName: 'McDonald',
        done: false
      },
      {
        firstName: 'Alex',
        lastName: 'Nemeth',
        done: false
      },
      {
        firstName: 'Nate',
        lastName: 'Kostansek',
        done: true
      },
      {
        firstName: 'Ivan',
        lastName: 'Wyrsta',
        done: true
      }
    ]
  },
  puted: {
    fullName: function(name) {
      return name.lastName + ', ' + name.firstName;
    }      
  }
  methods: {
    toggle: function(name) {
      name.done = !name.done;
    }
  }
});
<script src="/[email protected]/dist/vue.js"></script>
<div id='app'>
  <ol>
    <li v-for='name in names'>
      <input type='checkbox' v-bind:checked='name.done' v-on:change='toggle(name)' />
      <span v-if='!name.done'>{{ fullName(name) }}</span>
      <del v-else>{{ fullName(name) }}</del>
    </li>
  </ol>
</div>

I have an array of objects inside my Vue instance, and for each item I'd like to write a Computed property.

Each object has only two properties: firstName and lastName. I would like to write a Computed property for each named 'fullName', which is just a concatenation of firstName and lastName.

I'm familiar with implementing Computed properties of data object properties of a Vue instances, but when it es to doing so with elements of an array, I get confused.

Currently, my code is this:

var app = new Vue({
  el: '#app',
  data: {
    names: [{
        firstName: 'Mike',
        lastName: 'McDonald',
        done: false
      },
      {
        firstName: 'Alex',
        lastName: 'Nemeth',
        done: false
      },
      {
        firstName: 'Nate',
        lastName: 'Kostansek',
        done: true
      },
      {
        firstName: 'Ivan',
        lastName: 'Wyrsta',
        done: true
      }
    ]
  },
  puted: {
    fullName: function(name) {
      return name.lastName + ', ' + name.firstName;
    }      
  }
  methods: {
    toggle: function(name) {
      name.done = !name.done;
    }
  }
});
<script src="https://cdn.jsdelivr/npm/[email protected]/dist/vue.js"></script>
<div id='app'>
  <ol>
    <li v-for='name in names'>
      <input type='checkbox' v-bind:checked='name.done' v-on:change='toggle(name)' />
      <span v-if='!name.done'>{{ fullName(name) }}</span>
      <del v-else>{{ fullName(name) }}</del>
    </li>
  </ol>
</div>

And here is the respective jsFiddle

Share Improve this question edited Jul 23, 2020 at 23:10 Boussadjra Brahim 1 asked Nov 20, 2018 at 16:04 DelfinoDelfino 1,0094 gold badges22 silver badges47 bronze badges 1
  • 1 Try to reduce the number of function calls in your template. The function results are not cached, meaning that pretty much every change in data causes a full re-render. Using a puted, by creating an array of pre-puted objects can greatly improve your apps performance. See @Boussadjra's updated (2nd) example – Daniel Commented Nov 20, 2018 at 16:31
Add a ment  | 

2 Answers 2

Reset to default 7

It's remended to return a function with name as argument from the puted property :

var app = new Vue({
  el: '#app',
  data: {
    names: [{
        firstName: 'Mike',
        lastName: 'McDonald',
        done: false
      },
      {
        firstName: 'Alex',
        lastName: 'Nemeth',
        done: false
      },
      {
        firstName: 'Nate',
        lastName: 'Kostansek',
        done: true
      },
      {
        firstName: 'Ivan',
        lastName: 'Wyrsta',
        done: true
      }
    ]
  },
  puted: {
     fullName(){
      return (name)=>name.lastName + ', ' + name.firstName;
    },
     toggle() {
       return (name)=>name.done = !name.done;
    }
  },
});
<script src="https://cdn.jsdelivr/npm/[email protected]/dist/vue.js"></script>
<div id='app'>
  <ol>
    <li v-for='name in names'>
      <input type='checkbox' v-bind:checked='name.done' v-on:change='toggle(name)' />
      <span v-if='!name.done'>{{ fullName(name) }}</span>
      <del v-else>{{ fullName(name) }}</del>
    </li>
  </ol>
</div>

Another solution is to loop through names array inside a puted property by concatenating firstname and lastname, after that return this array and loop through it in your template

var app = new Vue({
  el: '#app',
  data: {
    names: [{
        firstName: 'Mike',
        lastName: 'McDonald',
        done: false
      },
      {
        firstName: 'Alex',
        lastName: 'Nemeth',
        done: false
      },
      {
        firstName: 'Nate',
        lastName: 'Kostansek',
        done: true
      },
      {
        firstName: 'Ivan',
        lastName: 'Wyrsta',
        done: true
      }
    ]
  },
  puted: {
    fullNames() {
      return this.names.map(name => {
        let fl = {};
        fl.fname = name.firstName + ", " + name.lastName;
        fl.done = name.done;
        return fl;
      })
    }
  },
  methods: {
    fullName: function(name) {
      return name.lastName + ', ' + name.firstName;
    },
    toggle: function(name) {
      name.done = !name.done;
    }
  }
});
<script src="https://cdn.jsdelivr/npm/[email protected]/dist/vue.js"></script>
<div id='app'>
  <ol>
    <li v-for='name in fullNames'>
      <input type='checkbox' v-bind:checked='name.done' v-on:change='toggle(name)' />
      <span v-if='!name.done'>{{ name.fname }}</span>
      <del v-else>{{  name.fname  }}</del>
    </li>
  </ol>
</div>

You can't use the 'puted' with a parameter. Most probably you want to use a method:

example

<span>{{ fullName('Hi') }}</span>

methods: {
  fullName(param) {
      return `${this.param} ${this.firstName} ${this.lastName}`
  }
}
发布评论

评论列表(0)

  1. 暂无评论