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

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.

主站蜘蛛池模板: 芦山县| 平阴县| 航空| 盈江县| 新密市| 隆德县| 奇台县| 绍兴市| 漳浦县| 石门县| 榆树市| 富阳市| 通城县| 抚顺县| 濮阳县| 那坡县| 平昌县| 平定县| 武山县| 灵山县| 新密市| 新巴尔虎右旗| 桓台县| 东海县| 庆城县| 安溪县| 兰考县| 茂名市| 米泉市| 德格县| 紫阳县| 遵义市| 射阳县| 桐乡市| 富蕴县| 磐石市| 邯郸县| 庄浪县| 东莞市| 龙口市| 昆山市|