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

  • 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.

主站蜘蛛池模板: 临泉县| 军事| 中阳县| 仙游县| 博兴县| 寿宁县| 崇仁县| 乌拉特后旗| 宝山区| 新宾| 永宁县| 射阳县| 屯门区| 德清县| 博湖县| 尉氏县| 嘉黎县| 绵竹市| 宿松县| 遵义市| 哈密市| 建始县| 托克逊县| 凤阳县| 松溪县| 瑞丽市| 浮山县| 靖江市| 怀集县| 承德市| 柘荣县| 嘉鱼县| 乐山市| 永仁县| 张家口市| 历史| 藁城市| 平陆县| 赤城县| 新和县| 来宾市|