官术网_书友最值得收藏!

Formatted value functions

When it comes to moving the format() function to the component for formatting our data, we are faced with two options. We can move it like-for-like and put it in the methods object, or we can take advantage of the Vue caching and conventions and create a computed function for each value.

We are building this app for scalability, so it's advisable to make computed functions for each value—it will also have the advantage of tidying up our template. Create three functions in the computed object titled balance, dateRegistered, and status. Copy the corresponding parts of the format function across to each one, updating the reference of person to this.person once more.

Where we were retrieving the field using a function parameter, you can now fix the value in each function. You will also need to add a data object with the currency symbol for the balance function—add this after the props:

      data() {
return {
currency: '$'
}
},

As the team-member component is the only place our currency symbol is used, we can remove it from the Vue app itself. We can also remove the format function from our parent Vue instance.

In total, our Vue team-member component should look like:

      Vue.component('team-member', {
template: '#team-member-template',
props: {
person: Object
},
data() {
return {
currency: '$'
}
},
computed: {
/**
* CSS Classes
*/
activeClass() {
return this.person.isActive ? 'active' :
'inactive';
},
balanceClass() {
let balanceLevel = 'success';
if(this.person.balance < 2000) {
balanceLevel = 'error';
} else if (this.person.balance < 3000) {
balanceLevel = 'warning';
}
let increasing = false,
balance = this.person.balance / 1000;
if(Math.round(balance) == Math.ceil(balance))
{
increasing = 'increasing';
}
return [balanceLevel, increasing];
},
/**
* Fields
*/
balance() {
return this.currency +
this.person.balance.toFixed(2);
},
dateRegistered() {
let registered = new
Date(this.person.registered);
return registered.toLocaleString('en-US');
},
status() {
return (this.person.isActive) ? 'Active' :
'Inactive';
}
}
});

And our team-member-template should look fairly simple in comparison to what it did look like:

      <script type="text/x-template" id="team-member-
template">
<tr v-show="filterRow()">
<td>
{{ person.name }}
</td>
<td>
<a v-bind:href="'mailto:' + person.email">{{
person.email }}</a>
</td>
<td v-bind:class="balanceClass">
{{ balance }}
</td>
<td>
{{ dateRegistered }}
</td>
<td v-bind:class="activeClass">
{{ status }}
</td>
</tr>
</script>

And lastly, our Vue instance should look significantly smaller:

      const app = new Vue({
el: '#app',
data: {
people: [...],
filter: {
field: '',
query: ''
}
},
methods: {
isActiveFilterSelected() {
return (this.filter.field === 'isActive');
},
/**
* Filtering
*/
filterRow(person) {
let visible = true,
field = this.filter.field,
query = this.filter.query;
if(field) {
if(this.isActiveFilterSelected()) {
visible = (typeof query === 'boolean') ?
(query === person.isActive) : true;
} else {
query = String(query),
field = person[field];
if(typeof field === 'number') {
query.replace(this.currency, '');
try {
visible = eval(field + query);
} catch(e) {}
} else {
field = field.toLowerCase();
visible =
field.includes(query.toLowerCase())
}
}
}
return visible;
}
changeFilter(event) {
this.filter.query = '';
this.filter.field = event.target.value;
}
}
});

Viewing the app in the browser, we should be presented with our list of people with the correct classes added to the table cells and formatting added to the fields.

主站蜘蛛池模板: 平遥县| 天柱县| 巴楚县| 集安市| 石棉县| 汽车| 绍兴县| 塔河县| 宁乡县| 乌兰浩特市| 榆社县| 潞城市| 霞浦县| 巫山县| 承德市| 景洪市| 双鸭山市| 彭阳县| 漳平市| 常州市| 澎湖县| 如皋市| 克拉玛依市| 迁西县| 韩城市| 建宁县| 双辽市| 曲周县| 梁河县| 黄石市| 陇西县| 交城县| 武强县| 莱阳市| 芦溪县| 乡宁县| 思南县| 大田县| 资兴市| 宕昌县| 太湖县|