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

  • Vue.js 2.x by Example
  • Mike Street
  • 475字
  • 2021-07-02 20:00:32

Making the filtering work again with props

Re-add the v-show="filterRow()" attribute to the containing tr element in your template. As our component has the person cached on each instance, we no longer need to pass the person object to the method. Refreshing the page will give you a new error in your JavaScript console:

Property or method "filterRow" is not defined on the instance but referenced during render

This error is because our component has the v-show attribute, showing and hiding based on our filtering and properties, but not the corresponding filterRow function. As we don't use it for anything else, we can move the method from the Vue instance to the component, adding it to the methods component. Remove the person parameter and update the method to use this.person:

      filterRow() {
let visible = true,
field = this.filter.field,
query = this.filter.query;
if(field) {
if(this.isActiveFilterSelected()) {
visible = (typeof query === 'boolean') ?
(query === this.person.isActive) : true;
} else {

query = String(query),
field = this.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;
}

The next error in the console is:

Cannot read property 'field' of undefined

The reason the filtering does not work is that the filterRow method is looking for this.filter.field and this.filter.query on the component, not the parent Vue instance where it belongs.

As a quick fix, you can use this.$parent to reference data on the parent element—however, this is not recommended and should only be used in extreme circumstances or to quickly pass the data through.

To pass the data through to the component we are going to use another prop - similar to how we are passing the person into the component. Fortunately, we had grouped our filtering data already, so we are able to pass that one object instead of inpidual properties of query or field. Create a new prop on your component titled filter and ensure you only allow an Object to be passed through:

      props: {
person: Object,
filter: Object
},

We can then add the prop to the team-member component, allowing us to pass the data:

      <table>
<template v-for="inpidual in people">
<team-member v-bind:person="inpidual" v-
bind:filter="filter"
></team-member>
</template>
</table>

In order for our filtering to work, we need to pass in one more property- the isActiveFilterSelected() function. Create another prop, titled statusFilter, allowing only a Boolean to be the value (as this is what the function equates to), and pass the function through. Update the filterRow method to use this new value. Our component now looks like:

      Vue.component('team-member', {
template: '#team-member-template',
props: {
person: Object,
filter: Object,
statusFilter: Boolean
},
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.registered);
return registered.toLocaleString('en-US');
},
status() {
return output = (this.person.isActive) ?
'Active' : 'Inactive';
}
},
methods: {
filterRow() {
let visible = true,
field = this.filter.field,
query = this.filter.query;

if(field) {
if(this.statusFilter) {
visible = (typeof query === 'boolean') ?
(query === this.person.isActive) : true;
} else {
query = String(query),
field = this.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;
}
}
});

And the component within the View with the extra props now looks like the following. Note that the camel-cased prop becomes snake case (hyphenated) when used as an HTML attribute:

      <template v-for="inpidual in people">
<team-member v-bind:person="inpidual" v- bind:filter="filter" v-bind:status-
filter="isActiveFilterSelected()"
></team-
member>
</template>
主站蜘蛛池模板: 高安市| 周口市| 宜春市| 育儿| 兰西县| 武宁县| 太湖县| 惠安县| 南汇区| 肃北| 珲春市| 绥棱县| 平昌县| 东宁县| 水城县| 安福县| 任丘市| 上蔡县| 资阳市| 鄂温| 简阳市| 东乡| 凌海市| 大邑县| 阿克苏市| 新竹县| 巴南区| 商洛市| 卢龙县| 佳木斯市| 谷城县| 民勤县| 东源县| 灌云县| 武冈市| 邛崃市| 筠连县| 大姚县| 水城县| 阳春市| 油尖旺区|