Maison >interface Web >js tutoriel >Méthode de mise en œuvre du filtrage dynamique des données du projet Vue

Méthode de mise en œuvre du filtrage dynamique des données du projet Vue

不言
不言avant
2018-11-16 16:46:163960parcourir

Le contenu de cet article concerne la méthode de mise en œuvre du filtrage dynamique des données du projet Vue. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.

Ce problème est un scénario réel que j'ai rencontré en travaillant sur un projet Vue. Voici un compte rendu de mes réflexions après avoir rencontré le problème et comment je l'ai finalement résolu (les anciens programmeurs ont de mauvais souvenirs

Le problème est le suivant :

Les données que la page obtient de l'arrière-plan sont composées de clés telles que 0 et 1, et la valeur représentée par cette clé, telle que 0-femelle et 1-mâle, est la relation correspondante. Obtenue à partir d'une autre interface de dictionnaire de données

类似于这样的Api:

{
  "SEX_TYPE": [
    { "paramValue": 0, "paramDesc": "女" },
    { "paramValue": 1, "paramDesc": "男" }
  ]
}

Ensuite, si la vue obtient 0, elle doit trouver sa description dans le dictionnaire et l'afficher ; 1. Réflexion

Certaines personnes disent, n'est-ce pas ce que le filtre est censé faire ? Utilisez simplement Vue.filter directement

Cependant, le problème est que ce filtre doit attendre. données asynchrones. L'interface du dictionnaire ne peut être obtenue qu'après le retour. Si ce filtre n'est pas trouvé lors de $mount,

provoquera une erreur et affectera le rendu ultérieur (écran blanc et erreur non définie) ; >Moi. Deux solutions me viennent à l'esprit :

Changer l'interface en synchronisation et obtenir l'interface du dictionnaire de données de manière synchrone dans le hook beforeCreate ou créé pour s'assurer qu'elle peut être enregistrée. quand $mounting Le filtre assure le timing, mais cela bloquera le montage et prolongera le temps d'écran blanc, il n'est donc pas recommandé

  • Changez l'enregistrement du filtre en asynchrone et avertissez le rendu ; observateur des mises à jour après avoir obtenu le filtre De cette façon, vous pouvez utiliser la propre réactivité de vue pour mettre à jour la vue sans bloquer le rendu, cette méthode est donc initialement adoptée ci-dessous

  • 2. >

    En raison du filtre. Appartenant à Asset_types, il existe les conclusions suivantes sur la chaîne d'accès des Asset_types dans les instances Vue
Pour les pratiques de code spécifiques, veuillez vous référer à : Codepen - test de filtre

asset_types inclut des filtres, des composants, des directives, tous les Asset_types suivants sont remplacés par les précédents

    Les Asset_types du composant enfant ne peuvent pas accéder aux Asset_types du composant parent, mais peut accéder au montage enregistré globalement. Les Asset_types sur $root.$options.asset_types.__proto__ correspondent au code source src/core/util/options.js
  • global. méthode d'enregistrement Vue.asset_types, telle que Vue.filters Les Asset_types enregistrés seront montés sur $options.asset_types.__proto__ de l'instance racine ($racine des autres instances) et seront hérités par toutes les instances Vue créées à l'avenir. C'est-à-dire que toutes les instances Vue créées dans le futur sont accessibles
  • La portée de l'emplacement d'un composant est limitée à l'endroit où il est défini, c'est-à-dire dans le composant. dans lequel il est défini. Les types d'actifs du composant parent ne sont pas accessibles, mais ceux définis globalement sont accessibles de la même manière, car la nouvelle instance Vue() dans main. js est l'instance racine, lesasset_types qui y sont enregistrés seront montés sur $root.$options.asset_types Pas sur $root.$options.asset_types.__proto__
  • Sur la base de ce qui précède. conclusions, vous pouvez commencer à coder~
  • 2.1 Utiliser les filtres du composant racine
  • Donc la première chose que je considère est de monter le filtre pour qu'il soit enregistré sur le composant racine, donc que d'autres composants peuvent obtenir le filtre enregistré en accédant à $root.

    Implémentation ici :

Enregistrer le filtre js

Cela rend les filtres du composant racine réactifs et les restitue C'est parce que $root.$ les options.filters qui ont été créés de manière réactive lors de la création sont accessibles dans la méthode rootFilters.
Ainsi, lorsque les données obtenues de manière asynchrone sont attribuées à $root.$options.filters, cela déclenchera le nouveau rendu de l'observateur de rendu de ce composant. À ce moment, le filtre peut être obtenu lorsque les rootFilters. est obtenue ;

Alors pourquoi ne pas vous inscrire directement avec la méthode Vue.filter ici.

<template>
  <div>
    {{ rootFilters( sexVal )}}
  </div>
</template>

<script type=&#39;text/javascript&#39;>
  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>
Parce que Object.defineProperty ne peut pas surveiller les modifications des données sur __proto__.

Le Vue.filter global enregistre le filtre sur le composant racine $root.$options.asset_types.__proto__, de sorte que ses modifications ne peuvent pas recevoir de réponse.
// 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,返回的是promise
    .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'))
}

Le code ici peut être encore amélioré, mais il y a certains problèmes avec cette méthode. Tout d'abord, une méthode instable sur Vue.util est utilisée ici.

De plus, vous pouvez voir this.$root.$options accéder aux propriétés internes de l'instance de vue partout pendant l'utilisation, ce qui n'est pas très civilisé et déroutant à lire.

Alors, lorsque ce projet a été terminé et en attente des tests, j'y ai pensé. Qui a dit que les filtres devaient être placés dans des filtres -. -, vous pouvez également utiliser mixin pour y parvenir

2.2 Utiliser mixin

Soyez prudent lorsque vous utilisez mixin, car vue traite toutes les variables commençant par _ et $ dans les données comme des variables internes réservées .

n'effectue pas de proxy vers l'instance actuelle, donc this._xx n'est pas accessible directement et doit être accessible via this.$data._xx.

Enregistrez la promesse de l'API ici. Si elle est utilisée ailleurs, elle renverra directement la promesse qui est déjà dans l'état résolu, il n'est donc pas nécessaire de demander à nouveau des données.

De plus, afin de faciliter l'accès dans d'autres instances, il est monté sur le composant racine. Comment l'utiliser dans notre composant racine :

// src/main.js

import sysParamsMixin from 'mixins/sysParamsMixin'

new Vue({
  el: '#app',
  mixins: [sysParamsMixin],
  render: h => h(App),
})

在需要用过滤器的组件中:

<template>
  <div>
    {{ $root._rootFilters( sexVal )}}
  </div>
</template>

<script type=&#39;text/javascript&#39;>
  export default {
    data() {
      return { sexVal: 1 }
    },
    mounted() {
      this.$root._getSysParamsFunc()
        .then(data =>
          // 这里获取到数据字典的data
        )
    }
  }
</script>

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

当然如果使用vuex更好,不过这里的场景个人觉得没必要用vuex,如果还有更好的方法可以讨论一下下啊~

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer