search
HomeWeb Front-endJS TutorialThe 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:

  1. Change the interface to synchronization, and obtain the data dictionary interface synchronously in the beforeCreate or created 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;

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

  1. asset_types includes filters, components, directives, all of the following asset_types are replaced by the previous items

  2. asset_types in the sub-component cannot access asset_types in the parent component. However, you can access the globally registered asset_types mounted on $root.$options.asset_types.__proto__, which corresponds to the source code src/core/util/options.js

  3. 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 ($root of 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 the

  4. component. 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 defined asset_types

  5. can be accessed.
  6. Similarly, because the new Vue() instance in main.js is the root instance, the asset_types registered in it will be mounted in $ root.$options.asset_types instead of $root.$options.asset_types.__proto__

## Based on the above conclusions, you can start coding ~

2.1 Using the filters of the root component

So the first thing I consider is to mount the filter to be registered on the root component, so that other components can access it by accessing

$root You can get the registered filter. The implementation here:

<template>
  <p>
    {{ rootFilters( sexVal )}}
  </p>
</template>
 
<script>
  import Vue from &#39;vue&#39;
  import { registerFilters } from &#39;utils/filters&#39;
 
  export default {
    data() {
      return {
        sexVal: 1  // 性别
      }
    },
    methods: {
      /* 根组件上的过滤器 */
      rootFilters(val, id = &#39;SEX_TYPE&#39;) {
        const mth = this.$root.$options.filters[id]
        return mth && mth(val) || val
      }
    },
    created() {
      // 把根组件中的filters响应式化
      Vue.util.defineReactive(this.$root.$options, &#39;filters&#39;, 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;

Why not use Vue here? The .filter method is registered directly, because

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.

The code here can be further improved, but there are certain problems with this method. First of all, an unstable method on

Vue.util is used here. In addition, it can be seen everywhere in usethis .$root.$optionsThis way of accessing the internal properties of the vue instance is not very civilized and confusing to read.

So when this project was completed and waiting for testing, I thought about it. Who said filters must be placed in filters -. -, you can also use mixin to achieve it

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 &#39;api&#39;
  import sysParamsMixin from &#39;mixins/sysParamsMixin&#39;
 
  export default {
    mixins: [sysParamsMixin],
    data() {
      return { sexVal: 1 }
    },
    mounted() {
      this._getSysParamsFunc()
        .then(data =>
          // 这里获取到数据字典的data
        )
    }
  }
</script>

这里不仅注册了过滤器,而且也暴露了数据字典,以方便某些地方的列表显示,毕竟这是实际项目中常见的场景。

相关推荐:

如何在项目中使用Vue+animate过渡动画

Vue过滤器filters使用详解

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!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
From Websites to Apps: The Diverse Applications of JavaScriptFrom Websites to Apps: The Diverse Applications of JavaScriptApr 22, 2025 am 12:02 AM

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 vs. JavaScript: Use Cases and Applications ComparedPython vs. JavaScript: Use Cases and Applications ComparedApr 21, 2025 am 12:01 AM

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.

The Role of C/C   in JavaScript Interpreters and CompilersThe Role of C/C in JavaScript Interpreters and CompilersApr 20, 2025 am 12:01 AM

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 in Action: Real-World Examples and ProjectsJavaScript in Action: Real-World Examples and ProjectsApr 19, 2025 am 12:13 AM

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.

JavaScript and the Web: Core Functionality and Use CasesJavaScript and the Web: Core Functionality and Use CasesApr 18, 2025 am 12:19 AM

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 the JavaScript Engine: Implementation DetailsUnderstanding the JavaScript Engine: Implementation DetailsApr 17, 2025 am 12:05 AM

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 vs. JavaScript: The Learning Curve and Ease of UsePython vs. JavaScript: The Learning Curve and Ease of UseApr 16, 2025 am 12:12 AM

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 vs. JavaScript: Community, Libraries, and ResourcesPython vs. JavaScript: Community, Libraries, and ResourcesApr 15, 2025 am 12:16 AM

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.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

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

Hot Tools

MantisBT

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

Dreamweaver Mac version

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

WebStorm Mac version

WebStorm Mac version

Useful JavaScript development tools