时间:2022-06-21 10:01:08 | 栏目:vue | 点击:次
同一个链接需要加载不同的页面组件。根据用户所购买服务的不同,有不同的页面展现。
在配置路由的地方获取服务器数据动态加载对应的组件
{ path: 'shopKPI', // 如果提前把后台数据存到store里面,在这里访问store数据,可以直接判断出来 // 但这种特定业务页面的数据放全局store,其他地方也不用,实在没有必要 component: () => import('@/views/store/dataVersion'), name: 'store_KPI', menuName: '店铺参谋', meta: { codes: ['storeProduct.detail'] } }
理想很美好,现实的情况是,component接收的这个方法必须要同步的返回一个promise。
这时候我想到了上面不好的实现方式1,稍微加以改造
<!-- ChooseShopKPI.vue --> <template> <dataVersion v-if="!useNewShopKPI" /> <ShopKPI v-else /> </template> <script> import { get } from 'lodash'; import { getStoreReportFormVersion } from '@/api/store'; import dataVersion from './dataVersion'; import ShopKPI from './ShopKPI'; export default { name: 'ChooseShopKPI', components: { dataVersion, ShopKPI, }, data() { return { useNewShopKPI: false }; }, created() { getStoreReportFormVersion().then((res) => { if (get(res, 'data.data.new')) { this.useNewShopKPI = true; } }); }, }; </script> <style lang="css" scoped></style>
把路由渲染对应的页面,改为渲染这个中间页面ChooseShopKPI
{ path: 'shopKPI', // 如果提前把后台数据取到,在这里访问store数据,可以直接判断出来 // 但这种特定业务页面的数据放全局store,其他地方也不用,实在没有必要 - component: () => import('@/views/store/dataVersion'), + component: () => import('@/views/store/ChooseShopKPI'), name: 'store_KPI', menuName: '店铺参谋', meta: { codes: ['storeProduct.detail'] } }
这样就实现了我们期望的功能。
这种方式虽然很好的解决了动态加载页面组件的问题。但也产生了一些小问题。
通过对ChooseXXX进行抽象,改造为DynamicLoadComponent
<!-- DynamicLoadComponent.vue --> <template> <component :is="comp" /> </template> <script> export default { name: 'DynamicLoadComponent', props: { renderComponent: { type: Promise, }, }, data() { return { comp: () => this.renderComponent } }, mounted() {}, }; </script> <style lang="css" scoped></style>
直接在路由的配置中获取后台数据,并进行路由的分发。这样路由逻辑都集中在路由配置文件中,没有二次路由。维护起来不会头疼脑胀。
DynamicLoadComponent组件也得以复用,后续新增判断后台数据加载页面的路由配置,都可以导向这个中间组件。
{ path: 'shopKPI', component: () => import('@/views/store/components/DynamicLoadComponent'), name: 'store_KPI', menuName: '店铺参谋', meta: { codes: ['storeProduct:detail'], }, props: (route) => ({ renderComponent: new Promise((resolve, reject) => { getStoreReportFormVersion() .then((responseData) => { const useNewShopKPI = get(responseData, 'data.data.shop_do'); const useOldShopKPI = get( responseData, 'data.data.store_data_show' ); if (useNewShopKPI) { resolve(import('@/views/store/ShopKPI')); } else if (useOldShopKPI) { resolve(import('@/views/store/dataVersion')); } else { resolve(import('@/views/store/ShopKPI/NoKPIService')); } }) .catch(reject); }), }) }
查看在线小例子(只支持chrome)
https://stackblitz.com/edit/vuejs-starter-jsefwq?file=index.js