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

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

Reducing the number of filter variables and grouping logically

The filtering currently uses up three variables, filterFieldfilterQuery, and filterUserState. The only thing that currently links these variables is the name, rather than being in an object of their own to link them systematically. Doing this avoids any ambiguity as to whether they are related to the same component or just coincidentally the same. In the data object, create a new object titled filter and move each variable inside:

      data: {
people: [..],
currency: '$',
filter: {
field: '',
query: '',
userState: '',
}
}

To access the data, update any references of filterField to this.filter.field. Note the extra dot, denoting it is a key of the filter object. Don't forget to update filterQuery and filterUserState references as well. For example, the isActiveFilterSelected method would become:

      isActiveFilterSelected() {
return (this.filter.field === 'isActive');
}

You will also need to update the v-model and v-show attributes in your view—there are five occurrences of the various variables.

While updating the filtering variables, we can take this opportunity to remove one. With our current filtering, we can only have one filter active at a time. This means the query and userState variables are only being used at any one time, which gives us the opportunity to combine these two variables. To do so, we'll need to update the view and application code to cater for this.

Remove the userState variable from your filter data object and update any occurrence of filter.userState in your view to filter.query. Now do a find and replace in your Vue JavaScript code for filter.userState, again replacing it with filter.query

Viewing your app in the browser, it will appear to initially work, being able to filter users by the field. However, if you filter by status, then switch to any other field, the query field won't show. This is because using the radio buttons sets the value to a Boolean which, when trying to convert to lowercase for the query field, fails to do so. To tackle this, we can convert whatever value is in the filter.query variable to a string using the native JavaScript String() function. This ensures that our filtering function can work with any filtering input:

      if(this.filter.field === 'isActive') {
result = (typeof this.filter.query ===
'boolean') ? (this.filter.query ===
person.isActive) : true;
} else {
let query = String(this.filter.query),
field = person[this.filter.field];
if(typeof field === 'number') {
query.replace(this.currency, '');
try {
result = eval(field + query);
} catch(e) {}
} else {
field = field.toLowerCase();
result = field.includes(query.toLowerCase());
}

Adding this to our code now ensures our query data is usable no matter what the value. The issue this now creates is when the user is switching between fields to filter. If you select the Active user and chose a radio button, the filtering works as expected, however, if you now switch to Email, or another field, the input box is prepopulated with either true or false. This instantly filters and will often return no results. This also occurs when switching between two text filtering fields, which is not the desired effect.

What we want is, whenever the select box is updated, the filter query should clear. Whether it is the radio buttons or input box, selecting a new field should reset the filter query, this ensures a new search can begin.

This is done by removing the link between the select box and the filter.field variable and creating our own method to handle the update. We then trigger the method when the select box is changed. This method will then clear the query variable and set the field variable to the select box value.

Remove the v-model attribute on the select box and add a new v-on:change attribute. We will pass a method name into this that will fire every time the select box is updated.

v-on is a new Vue binding that we've not encountered before. It allows you to bind actions from elements to Vue methods. For example, v-on:click is one that is used the most commonly - which allows you to bind a click function to the element. We'll cover more on this in the next section of the book.

Where v-bind can be abbreviated to just a colon, v-on can be shortened to an @ symbol, allowing you to use @click="", for example:

      <select v-on:change="changeFilter($event)"     
id="filterField">
<option value="">Disable filters</option>
<option value="isActive">Active user</option>
<option value="name">Name</option>
<option value="email">Email</option>
<option value="balance">Balance</option>
<option value="registered">Date
registered</option>
</select>

This attribute is firing the changeFilter method on every update and passing it the $event data of the change. This default Vue event object contains a lot of information that we could utilize, but the target.value data is the key we are after. 

Create a new method in your Vue instance that accepts the event parameter and updates both the query and field variables. The query variable needs to be cleared, so set it to an empty string, whereas the field variable can be set to the value of the select box:

      changeFilter(event) {
this.filter.query = '';
this.filter.field = event.target.value;
}

Viewing your application now should clear whatever the filter query is, while still operating as expected.

主站蜘蛛池模板: 肇庆市| 平罗县| 中西区| 水富县| 安吉县| 义乌市| 新宁县| 奉节县| 安多县| 临泽县| 历史| 望都县| 友谊县| 黄山市| 敦化市| 杭州市| 昆明市| 阳西县| 凤山县| 西峡县| 桐城市| 静乐县| 台东市| 汉中市| 四会市| 金平| 沙河市| 屏东市| 应城市| 应城市| 山西省| 丰顺县| 淅川县| 庄河市| 苍溪县| 饶河县| 蓝山县| 宁波市| 惠州市| 兰州市| 上栗县|