Vue Router根据后台数据加载不同的组件实现

作者:zhea55 时间:2023-07-02 16:59:14 

目录
  • 实际项目中遇到的需求

  • 有一些不好的实现方式

  • 个人感觉比较好的实现方式

  • 功能已实现,但我又开始了新的思考

  • 最终方案——高阶组件

实际项目中遇到的需求

同一个链接需要加载不同的页面组件。根据用户所购买服务的不同,有不同的页面展现。

有一些不好的实现方式

  • 直接把这几个组件写在同一个组件下,通过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);
   }),
 })
}

查看在线小例子(只支持chrome)
https://stackblitz.com/edit/vuejs-starter-jsefwq?file=index.js

来源:https://www.cnblogs.com/zhea55/p/15115555.html

标签:Vue,Router,数据加载
0
投稿

猜你喜欢

  • phpMyAdmin下载、安装和使用入门

    2007-06-15 11:00:00
  • JavaScript调用ajax获取文本文件内容实现代码

    2024-04-30 10:15:52
  • [译]Javascript风格要素(一)

    2008-02-28 12:58:00
  • 对python:threading.Thread类的使用方法详解

    2022-01-24 04:19:28
  • Python可变与不可变数据和深拷贝与浅拷贝

    2022-06-05 21:14:51
  • 使用sqlplus连接Oracle数据库问题

    2024-01-13 09:25:16
  • 网址站的2.0玩法

    2010-03-15 12:25:00
  • 一条sql 语句搞定数据库分页

    2009-03-21 18:32:00
  • java使用dbcp2数据库连接池

    2024-01-29 05:33:42
  • Python3.9新特性详解

    2023-03-26 21:56:16
  • Windows下pycharm安装第三方库失败(通用解决方案)

    2022-06-07 22:54:37
  • MySQL跨服务器数据映射的实现

    2024-01-23 15:08:19
  • 可以在线创建文件夹吗?

    2009-11-01 18:07:00
  • python pandas loc 布尔索引示例说明

    2021-02-28 22:43:19
  • MSSQL数据类型及长度限制详细说明

    2024-01-25 06:01:09
  • Mysql运行环境优化(Linux系统)

    2024-01-14 16:38:03
  • python 字符串转列表 list 出现\\ufeff的解决方法

    2023-11-24 18:47:06
  • 详解Python并发编程之创建多线程的几种方法

    2023-03-31 19:34:37
  • 快速掌握如何使用SQL Server来过滤数据

    2009-01-15 13:27:00
  • 微信公众平台开发教程③ PHP实现微信公众号支付功能图文详解

    2023-11-18 19:09:27
  • asp之家 网络编程 m.aspxhome.com