Heim  >  Artikel  >  Web-Frontend  >  Implementierungsmethode der dynamischen Filterung von Vue-Projektdaten

Implementierungsmethode der dynamischen Filterung von Vue-Projektdaten

不言
不言nach vorne
2018-11-16 16:46:163913Durchsuche

Der Inhalt dieses Artikels befasst sich mit der Implementierungsmethode der dynamischen Filterung von Vue-Projektdaten. Ich hoffe, dass er für Freunde hilfreich ist.

Dieses Problem ist ein tatsächliches Szenario, auf das ich bei der Arbeit an einem Vue-Projekt gestoßen bin. Hier schreibe ich meine Gedanken auf, nachdem ich auf das Problem gestoßen bin und wie ich es schließlich gelöst habe (alte Programmierer haben schlechte Erinnerungen

Das Problem ist folgendes:

Die Daten, die die Seite aus dem Hintergrund erhält, bestehen aus Schlüsseln wie 0 und 1, und der durch diesen Schlüssel dargestellte Wert, wie z. B. 0-weiblich und 1-männlich, ist der entsprechende Beziehung. Von einer anderen Datenwörterbuchschnittstelle erhalten;

类似于这样的Api:

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

Wenn die Ansicht dann 0 erhält, muss sie ihre Beschreibung aus dem Wörterbuch finden und sie anzeigen: 🎜>

Manche Leute sagen, ist das nicht das, was der Filter tun soll?

Das Problem ist jedoch, dass dieser Filter auf das asynchrone Datenwörterbuch warten muss Schnittstelle. Es kann nur nach der Rückkehr abgerufen werden,

es wird einen Fehler verursachen und sich auf das nachfolgende Rendern auswirken (weißer Bildschirm und undefinierter Fehler); Ich habe darüber nachgedacht. Es gibt zwei Lösungen:

Ändern Sie die Schnittstelle auf Synchronisierung und rufen Sie die Datenwörterbuchschnittstelle synchron im BeforeCreate- oder Created-Hook ab, um sicherzustellen, dass der registrierte Filter wann abgerufen werden kann $mounting, um das Timing sicherzustellen, aber dies blockiert die Bereitstellung und verlängert die Zeit des weißen Bildschirms. Es wird daher nicht empfohlen, die Registrierung des Filters auf asynchron zu ändern und zu benachrichtigen Der Render-Watcher aktualisiert sich nach dem Abrufen des Filters. Auf diese Weise kann die eigene Reaktionsfähigkeit von Vue verwendet werden, um die Ansicht zu aktualisieren, sodass diese Methode zunächst übernommen wird. Es gibt die folgenden Schlussfolgerungen zur Zugriffskette von asset_types Vue-Instanzen;

Informationen zu spezifischen Codepraktiken finden Sie unter: Codepen – Filtertest
  • asset_types umfasst Filter, Komponenten, Anweisungen, alle folgenden asset_types werden durch ersetzt vorherige
  • Die asset_types in der untergeordneten Komponente können nicht auf die asset_types in der übergeordneten Komponente zugreifen, aber Sie können auf den global registrierten Mount in $ asset_types im Stammverzeichnis zugreifen.$options.asset_types.__proto__, Dies entspricht dem Quellcode src/core/util/options.js

Globale Registrierungsmethode Vue.asset_types, wie die von Vue.filters registrierte asset_types, wird in $options eingebunden .asset_types.__proto__ der Root-Instanz ($root anderer Instanzen) und wird von allen in Zukunft erstellten Vue-Instanzen geerbt. Das heißt, alle in Zukunft erstellten Vue-Instanzen können auf

Der Bereich des Slots einer Komponente ist auf den Ort beschränkt, an dem er definiert ist, d

  • Da die neue Vue()-Instanz in main.js die Root-Instanz ist, werden die darin registrierten Asset_Types ebenfalls auf $root.$options.asset_types statt auf $ root gemountet .$options.asset_types.__proto__ auf

  • Basierend auf den obigen Schlussfolgerungen können Sie mit dem Codieren beginnen~

  • 2.1 Verwenden Sie die Filter der Stammkomponente

    Das erste, was ich in Betracht ziehe, ist, den zu registrierenden Filter auf der Root-Komponente bereitzustellen, damit andere Komponenten den registrierten Filter erhalten können, indem sie auf $root zugreifen.
  • Die Implementierung hier:

    <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>
    JS zum Registrieren des Filters
// 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'))
}
  • Dadurch reagieren die Filter auf der Root-Komponente und beim Rendern aufgrund der RootFilters Die Methode greift zu $root.$options.filters, die reaktiv erstellt wurden.

    Wenn also die asynchron erhaltenen Daten $root.$options.filters zugewiesen werden, wird das erneute Rendern des Render-Watchers dieser Komponente ausgelöst. Zu diesem Zeitpunkt kann der Filter abgerufen werden, wenn die rootFilters Methode erhalten wird;
  • Dann registrieren Sie sich doch direkt hier bei der Vue.filter-Methode.

    Weil Object.defineProperty Änderungen in Daten auf __proto__ nicht überwachen kann.

    Der globale Vue.filter registriert den Filter auf der Root-Komponente $root.$options.asset_types.__proto__, sodass auf seine Änderungen nicht reagiert werden kann.
    Der Code hier kann noch weiter verbessert werden, es gibt jedoch bestimmte Probleme mit dieser Methode. Erstens wird hier eine instabile Methode auf Vue.util verwendet.

    Außerdem können Sie sehen, dass $root.$options während der Verwendung überall auf die internen Eigenschaften der Vue-Instanz zugreift, was nicht sehr zivilisiert und verwirrend zu lesen ist.

    Als dieses Projekt abgeschlossen war und auf den Test wartete, dachte ich darüber nach: Wer hat gesagt, dass Filter in Filtern platziert werden müssen? -, Sie können auch Mixin verwenden, um dies zu erreichen

    2.2 Verwendung von Mixin

    Seien Sie vorsichtig bei der Verwendung von Mixin, da Vue alle Variablen, die in den Daten mit _ und $ beginnen, als interne reservierte Variablen behandelt .

    fungiert nicht als Proxy für die aktuelle Instanz, sodass auf this._xx nicht direkt zugegriffen werden kann und der Zugriff über this.$data._xx erfolgen muss.

    // mixins/sysParamsMixin.js
    
    import * as Api from 'api'
    
    export default {
      data() {
        return {
          _filterFunc: null,       // 过滤器函数
          _sysParams: null,        // 获取数据字典
          _sysParamsPromise: null  // 获取sysParams之后返回的Promise
        }
      },
      methods: {
        /* 注册过滤器到_filterFunc中 */
        _getSysParamsFunc() {
          const { $data } = this
          return $data._sysParamsPromise || ($data._sysParamsPromise = Api.sysParams()
            .then(({ data }) => {
              this.$data._sysParams = data
              this.$data._filterFunc = {}
              Object.keys(data).forEach(paramKey =>
                this.$data._filterFunc[paramKey] = val => {
                  const tar = data[paramKey].find(item => item['paramValue'] === val)
                  return tar && 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
        }
      }
    }
    Speichern Sie das Versprechen der API hier. Wenn es an anderer Stelle verwendet wird, wird das Versprechen, das sich bereits im gelösten Zustand befindet, direkt zurückgegeben, sodass keine erneute Datenanforderung erforderlich ist.

    Um den Zugriff in anderen Fällen zu erleichtern, wird es außerdem auf der Root-Komponente gemountet.

    So verwenden Sie es in unserer Root-Komponente:

    // 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,如果还有更好的方法可以讨论一下下啊~

    Das obige ist der detaillierte Inhalt vonImplementierungsmethode der dynamischen Filterung von Vue-Projektdaten. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

    Stellungnahme:
    Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen