Maison > Article > interface Web > Le processus de mise en œuvre du filtrage dynamique des données du projet Vue
Le contenu de cet article concerne le processus 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-.-), et le processus Cela impliquera certains concepts de code source Vue tels que $mount
, render watcher
, etc. Si vous n'en savez pas grand-chose, vous pouvez jeter un œil à la série de lecture de code source Vue ~
Le problème est le suivant : la page est obtenue depuis le backend Les données sont constituées de clés telles que 0
et 1
, et de la relation correspondante entre les valeurs représentées par cette clé, telles que 0-女
et 1-男
, doit être obtenu depuis une autre interface de dictionnaire de données ; similaire à cette 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 ; l'histoire commence ci-dessous
Certaines personnes disent que ce n'est pas ce que le filtre filter
devrait faire. Utilisez simplement Vue.filter directement. attendre le retour de l'interface du dictionnaire de données asynchrone avant de pouvoir l'obtenir. Si c'est le cas $mount
Lorsque ce filtre n'est pas trouvé, cela provoquera des erreurs qui affecteront le rendu ultérieur (écran blanc et erreur non définie
ou beforeCreate
pour garantir que le filtre enregistré peut être obtenu sur created
pour garantir le timing, mais cela bloquera le montage prolonge la durée de l'écran blanc, il n'est donc pas recommandé $mount
de se mettre à jour après avoir obtenu le filtre, afin que la propre réponse de la vue puisse être utilisée. Mettez à jour la vue de manière standardisée sans bloquer le rendu, cette méthode est donc initialement adoptée ci-dessous. render watcher
comprend asset_types
, filters
et components
Tous les directives
suivants seront remplacés par les précédents asset_types
<.>
dans le composant parent, mais il peut accéder au asset_types
enregistré globalement monté sur asset_types
, qui correspond au code source src/core /util/ options.js$root.$options.asset_types.__proto__
asset_types
d'autres instances), et hérité de toutes les instances Vue créées dans le futur, c'est-à-dire que toutes les instances Vue créées dans le futur peuvent accéder au composant $root
$options.asset_types.__proto__
asset_types
asset_types
au lieu de new Vue()
asset_types
$root.$options.asset_types
$root.$options.asset_types.__proto__
$root
Register filter js
<template> <p> {{ rootFilters( sexVal )}} </p> </template> <script type='text/javascript'> 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>
Cela rend les filtres sur le composant racine réactifs, et lors du rendu, car la méthode
accède à// 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')) }qui a été réactif lors de la création, donc lorsque les données obtenues de manière asynchrone sont affectées à
, cela se déclenchera le re-rendu du render watcher de ce composant, puis obtenir rootFilters
$root.$options.filters
Alors pourquoi ne pas l'enregistrer directement avec la méthode Vue.filter ici, car $root.$options.filters
ne peut pas surveiller les modifications des données sur rootFilters
, et le Vue.filter global est Le filtre est enregistré sur le composant racine
Object.defineProperty
Le code ici peut être encore amélioré, mais il y a certains problèmes avec cette méthode. Tout d'abord, la méthode unstable sur __proto__
est utilisée ici. De plus, on peut voir partout en cours d'utilisation que <.> accède ainsi aux propriétés internes de l'instance vue. La situation, peu civilisée, est également déroutante à lire. $root.$options.asset_types.__proto__
使用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 type='text/javascript'> 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>
这里不仅注册了过滤器,而且也暴露了数据字典,以方便某些地方的列表显示,毕竟这是实际项目中常见的场景。
相关推荐:
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!