The implementation process of dynamic filtering of Vue project data
The content of this article is about the implementation process of dynamic filtering of Vue project data. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.
This problem is an actual scenario I encountered while working on a Vue project. Here I record my thoughts after encountering the problem and how I finally solved it (old programmers have bad memory-.-), and the process It will involve some Vue source code concepts such as $mount
, render watcher
, etc. If you don’t know much about it, you can take a look at the Vue source code reading series~
Questions It is like this: the data the page gets from the background is composed of keys such as 0
, 1
, and the value represented by this key is such as 0-女
, The corresponding relationship of 1-Male
is to be obtained from another data dictionary interface; similar to this API:
{ "SEX_TYPE": [ { "paramValue": 0, "paramDesc": "女" }, { "paramValue": 1, "paramDesc": "男" } ] }
Then if the view gets 0
, you need to find its description from the dictionary 女
and display it; the following story begins
1. Thinking
Some people say that this is not a filterfilter
What to do, just use Vue.filter directly. However, the problem is that this filter has to wait for the asynchronous data dictionary interface to return before it can be obtained. If it is $mount
, If this filter is not found, it will cause errors that will affect subsequent rendering (white screen and undefined error);
I have two solutions in mind:
Change the interface to synchronization, and obtain the data dictionary interface synchronously in the
beforeCreate
orcreated
hook to ensure that the registered filter can be obtained at$mount
, to ensure the timing, but this will block the mount and extend the white screen time, so it is not recommended;Change the registration of the filter to asynchronous, and notify the
render watcher after getting the filter
Update yourself so that you can use vue's own responsiveness to update the view without blocking rendering, so this method is initially adopted below.
2. Implementation
Because filter belongs to asset_types, there are the following conclusions about the access chain of asset_types in Vue instances; for specific code practices, please refer to: Codepen - filter test
asset_types
includesfilters
,components
,directives
, all of the followingasset_types
are replaced by the previous items-
asset_types
in the sub-component cannot accessasset_types
in the parent component. However, you can access the globally registeredasset_types
mounted on$root.$options.asset_types.__proto__
, which corresponds to the source code src/core/util/options.js Global registration method Vue.asset_types, for example, the asset_types registered by Vue.filters will be mounted to the
$options.asset_types of the root instance (
$rootof other instances) .__proto__
, and is inherited by all Vue instances created in the future. That is to say, all Vue instances created in the future can access the slot of thecomponent. The scope of the slot is only Limited to the place where it is defined, that is, in the component in which it is defined, the
asset_types
of the parent component cannot be accessed, but the globally definedasset_types
can be accessed. Similarly, because the
new Vue()
instance in main.js is the root instance, theasset_types
registered in it will be mounted in$ root.$options.asset_types
instead of$root.$options.asset_types.__proto__
$root You can get the registered filter. The implementation here:
<template> <p> {{ rootFilters( sexVal )}} </p> </template> <script> import Vue from 'vue' import { registerFilters } from 'utils/filters' export default { data() { return { sexVal: 1 // 性别 } }, methods: { /* 根组件上的过滤器 */ rootFilters(val, id = 'SEX_TYPE') { const mth = this.$root.$options.filters[id] return mth && mth(val) || val } }, created() { // 把根组件中的filters响应式化 Vue.util.defineReactive(this.$root.$options, 'filters', this.$root.$options.filters) }, mounted() { registerFilters.call(this) .then(data => // 这里获取到数据字典的data ) } } </script>js for registering filter
// utils/filters import * as Api from 'api' /** * 获取并注册过滤器 * 注册在$root.$options.filters上不是$root.$options.filters.__proto__上 * 注意这里的this是vue实例,需要用call或apply调用 * @returns {Promise} */ export function registerFilters() { return Api.sysParams() // 获取数据字典的Api .then(({ data }) => { Object.keys(data).forEach(T => this.$set(this.$root.$options.filters, T, val => { const tar = data[T].find(item => item['paramValue'] === val) return tar['paramDesc'] || '' }) ) return data }) .catch(err => console.error(err, ' in utils/filters.js')) }This makes the filters on the root component responsive, and when rendering, because The
rootFilters method accesses
$root.$options.filters that has been responsively made in created, so when the asynchronously acquired data is assigned to
$root.$ options.filters will trigger the re-rendering of this component render watcher. At this time, you can get the filter when you get the
rootFilters method;
Object.defineProperty cannot monitor data changes on
__proto__, and the global Vue.filter registers the filter in the root component
$root .$options.asset_types.__proto__, so its changes cannot be responded to.
Vue.util is used here. In addition, it can be seen everywhere in use
this .$root.$optionsThis way of accessing the internal properties of the vue instance is not very civilized and confusing to read.
2.2 使用mixin
使用mixin要注意一点,因为vue中把data里所有以_
、$
开头的变量都作为内部保留的变量,并不代理到当前实例上,因此直接this._xx
是无法访问的,需要通过this.$data._xx
来访问。
// mixins/sysParamsMixin.js import * as Api from 'api' export default { data() { return { _filterFunc: null, // 过滤器函数 _sysParams: null, // 获取数据字典 _sysParamsPromise: null // 获取sysParams之后返回的Promise } }, methods: { /* 注册过滤器到_filterFunc中 */ _getSysParamsFunc() { const thisPromise = this.$data._sysParamsPromise return thisPromise || Api.sysParams() // 获取数据字典的Api .then(({ data }) => { this.$data._filterFunc = {} Object.keys(data).forEach(paramKey => this.$data._filterFunc[paramKey] = val => { // 过滤器注册到_filterFunc中 const tar = data[paramKey].find(item => item['paramValue'] === val) return tar['paramDesc'] || '' }) return data }) .catch(err => console.error(err, ' in src/mixins/sysParamsMixin.js')) }, /* 按照键值获取单个过滤器 */ _rootFilters(val, id = 'SEX_TYPE') { const func = this.$data._filterFunc const mth = func && func[id] return mth && mth(val) || val }, /* 获取数据字典 */ _getSysParams() { return this.$data._sysParams } }, mounted() { this.$data._filterFunc || (this.$data._sysParamsPromise = this._getSysParamsFunc()) } }
这里把Api
的promise保存下来,如果其他地方还用到的话直接返回已经是resolved
状态的promise,就不用再次去请求数据了。
那在我们的组件中怎么使用呢:
<template> <p> {{ _rootFilters( sexVal )}} </p> </template> <script> import * as Api from 'api' import sysParamsMixin from 'mixins/sysParamsMixin' export default { mixins: [sysParamsMixin], data() { return { sexVal: 1 } }, mounted() { this._getSysParamsFunc() .then(data => // 这里获取到数据字典的data ) } } </script>
这里不仅注册了过滤器,而且也暴露了数据字典,以方便某些地方的列表显示,毕竟这是实际项目中常见的场景。
相关推荐:
The above is the detailed content of The implementation process of dynamic filtering of Vue project data. For more information, please follow other related articles on the PHP Chinese website!

JavaScript is widely used in websites, mobile applications, desktop applications and server-side programming. 1) In website development, JavaScript operates DOM together with HTML and CSS to achieve dynamic effects and supports frameworks such as jQuery and React. 2) Through ReactNative and Ionic, JavaScript is used to develop cross-platform mobile applications. 3) The Electron framework enables JavaScript to build desktop applications. 4) Node.js allows JavaScript to run on the server side and supports high concurrent requests.

Python is more suitable for data science and automation, while JavaScript is more suitable for front-end and full-stack development. 1. Python performs well in data science and machine learning, using libraries such as NumPy and Pandas for data processing and modeling. 2. Python is concise and efficient in automation and scripting. 3. JavaScript is indispensable in front-end development and is used to build dynamic web pages and single-page applications. 4. JavaScript plays a role in back-end development through Node.js and supports full-stack development.

C and C play a vital role in the JavaScript engine, mainly used to implement interpreters and JIT compilers. 1) C is used to parse JavaScript source code and generate an abstract syntax tree. 2) C is responsible for generating and executing bytecode. 3) C implements the JIT compiler, optimizes and compiles hot-spot code at runtime, and significantly improves the execution efficiency of JavaScript.

JavaScript's application in the real world includes front-end and back-end development. 1) Display front-end applications by building a TODO list application, involving DOM operations and event processing. 2) Build RESTfulAPI through Node.js and Express to demonstrate back-end applications.

The main uses of JavaScript in web development include client interaction, form verification and asynchronous communication. 1) Dynamic content update and user interaction through DOM operations; 2) Client verification is carried out before the user submits data to improve the user experience; 3) Refreshless communication with the server is achieved through AJAX technology.

Understanding how JavaScript engine works internally is important to developers because it helps write more efficient code and understand performance bottlenecks and optimization strategies. 1) The engine's workflow includes three stages: parsing, compiling and execution; 2) During the execution process, the engine will perform dynamic optimization, such as inline cache and hidden classes; 3) Best practices include avoiding global variables, optimizing loops, using const and lets, and avoiding excessive use of closures.

Python is more suitable for beginners, with a smooth learning curve and concise syntax; JavaScript is suitable for front-end development, with a steep learning curve and flexible syntax. 1. Python syntax is intuitive and suitable for data science and back-end development. 2. JavaScript is flexible and widely used in front-end and server-side programming.

Python and JavaScript have their own advantages and disadvantages in terms of community, libraries and resources. 1) The Python community is friendly and suitable for beginners, but the front-end development resources are not as rich as JavaScript. 2) Python is powerful in data science and machine learning libraries, while JavaScript is better in front-end development libraries and frameworks. 3) Both have rich learning resources, but Python is suitable for starting with official documents, while JavaScript is better with MDNWebDocs. The choice should be based on project needs and personal interests.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

MantisBT
Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

Dreamweaver Mac version
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

PhpStorm Mac version
The latest (2018.2.1) professional PHP integrated development tool

WebStorm Mac version
Useful JavaScript development tools