この記事の内容は、Vue プロジェクト データの動的フィルタリングの実装方法に関するものです。必要な方は参考にしていただければ幸いです。
この問題は、私が Vue プロジェクトで作業中に遭遇した実際のシナリオです。ここでは、問題に遭遇した後の私の考えと、最終的にどのように解決したかを記録します (古いプログラマーには嫌な思い出があります)。
問題は次のとおりです:
ページが背景から取得したデータは、0や1などのキーと、このキーで表される値の対応関係(0-女性など)で構成されています。および 1-男性は、別のデータ ディクショナリ インターフェイスから取得されます。
类似于这样的Api: { "SEX_TYPE": [ { "paramValue": 0, "paramDesc": "女" }, { "paramValue": 1, "paramDesc": "男" } ] }
次に、ビューが 0 を取得した場合、その説明をディクショナリから見つけて表示する必要があります。
1 . 思考
しかし、問題は、このフィルターは、非同期データ ディクショナリ インターフェイス。$mount 時にこのフィルターが見つからない場合は、エラーが発生し、その後のレンダリングに影響します (白い画面と未定義のエラー)。 ##私が考えたこと。解決策は 2 つあります:
インターフェイスを同期に変更し、beforeCreate または created フックでデータ ディクショナリ インターフェイスを同期的に取得して、登録されたフィルターが確実に機能できるようにします。タイミングを確保するために $mounting 時に取得されますが、これによりマウントがブロックされ、白い画面時間が延長されるため、推奨されません。
2.1 ルート コンポーネントのフィルターを使用する
ここでの実装:
<template> <div> {{ rootFilters( sexVal )}} </div> </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>
// 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')) }
これにより、rootFilters メソッドは $root にアクセスするため、ルート コンポーネントのフィルターが応答しやすくなり、レンダリング時にも動作します。リアクティブな $options.filters が作成されました。
したがって、非同期で取得されたデータが $root.$options.filters に割り当てられると、このコンポーネントのレンダー ウォッチャーの再レンダリングがトリガーされます。このとき、フィルターは rootFilters のときに取得できます。メソッドが取得されます;それでは、ここで Vue.filter メソッドを直接登録してみてはいかがでしょうか。
2.2 mixin の使用
Vue はデータ内の _ と $ で始まるすべての変数を内部予約変数として扱うため、mixin を使用するときは注意してください。 。
は現在のインスタンスにプロキシしないため、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 { $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 } } }
API の Promise をここに保存します。API が他の場所で使用される場合は、すでに解決済みの状態にある Promise が直接返されるため、データを再度リクエストする必要はありません。
さらに、他のインスタンスからのアクセスを容易にするために、ルート コンポーネントにマウントされます。
ルートコンポーネントでの使用方法: 这里不仅注册了过滤器,而且也暴露了数据字典,以方便某些地方的列表显示,毕竟这是实际项目中常见的场景。 当然如果使用vuex更好,不过这里的场景个人觉得没必要用vuex,如果还有更好的方法可以讨论一下下啊~// 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='text/javascript'>
export default {
data() {
return { sexVal: 1 }
},
mounted() {
this.$root._getSysParamsFunc()
.then(data =>
// 这里获取到数据字典的data
)
}
}
</script>
以上がVueプロジェクトデータの動的フィルタリングの実装方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。