实际项目中遇到的需求同一个链接需要加载不同的页面组件 。根据用户所购买服务的不同,有不同的页面展现 。
有一些不好的实现方式
- 直接把这几个组件写在同一个组件下,通过v-if去判断 。如果这么做的话,甚至可以不使用vue-router,直接把所有组件,都写在一个文件里面,全部通过v-if判断,也是可行的 。(前提是几万行代码一起,你不嫌麻烦的话)
- 在渲染这个链接的时候,直接去请求后台的数据,通过数据渲染不同的链接 。(理论上是可行的,但如果用户没有用这个功能,这些链接每次都提前取了后台数据;另外如果用户知道了链接,直接访问链接,还是需要逻辑去判断用户该看到哪个页面)
- 通过调用
router.beforeEach,对每个路由进行拦截,当路由为我们指定的路由时,请求后台数据,动态跳转页面 。(功能是可以完成,但实际上,这只是整个系统的一小块功能,不应该侵入整个路由系统,如果每个业务页面,都写在全局路由系统,也会导致路由的逻辑过于复杂)
{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的中间页面 。 - 这种中间页面,实际上是做了二次路由,不熟悉逻辑的开发人员可能并不清楚这里面的页面跳转逻辑,增加了理解成本 。
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);}),})}【思考->实现->不止于实现 Vue Router根据后台数据加载不同的组件】查看在线小例子(只支持chrome)https://stackblitz.com/edit/vuejs-starter-jsefwq?file=index.js
- 春季老年人吃什么养肝?土豆、米饭换着吃
- 三八妇女节节日祝福分享 三八妇女节节日语录
- 老人谨慎!选好你的“第三只脚”
- 校方进行了深刻的反思 青岛一大学生坠亡校方整改校规
- 脸皮厚的人长寿!有这特征的老人最长寿
- 长寿秘诀:记住这10大妙招 100%增寿
- 春季老年人心血管病高发 3条保命要诀
- 眼睛花不花要看四十八 老年人怎样延缓老花眼
- 香槟然能防治老年痴呆症? 一天三杯它人到90不痴呆
- 老人手抖的原因 为什么老人手会抖
