Vue Router根据后台数据加载不同的组件(思考->实现->不止于实现)
实际项目中遇到的需求
同一个链接需要加载不同的页面组件。根据用户所购买服务的不同,有不同的页面展现。
有一些不好的实现方式
- 直接把这几个组件写在同一个组件下,通过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根据后台数据加载不同的组件(思考->实现->不止于实现)的更多相关文章
- vue 实现tab切换动态加载不同的组件
vue 实现tab切换动态加载不同的组件 使用vue中的is特性来加载不同的组件.具体看如下代码:这个功能对于vue比较复杂的页面可以使用上,可以把一个页面的功能拆分出来,使代码更简单.使用方式具体看 ...
- Vue – 基础学习(5):动态加载和注册组件
// var myComponent =() => import(`./../../components/custom_panel/${t_url}.vue`);// //var myCompo ...
- router 配置按需加载对应的组件,配置active
const routes = [ { path: '/', component: App, children: [ {path: '/index/:type', name: 'index', comp ...
- vue数据加载等待组件
关于loading组件的. loading.vue <template> <div class="loading"> <div class=" ...
- Vue中实现一个无限加载列表
参考 https://www.jianshu.com/p/0a3aebd63a14 一个需要判断的地方就是加载中再次触发滚动的时候,不要获取数据. <!DOCTYPE html> < ...
- 使用vue之directive设计列表加载更多
背景 之前写过一篇<纯JS实现加载更多(VUE框架)>,它的逻辑思路比较清晰易懂,而今天看了一天公司项目的部分功能代码,发现同事们写的加载更多的功能更加的有趣,而且易于封装到一个组件当中, ...
- Android 三级联动选择城市+后台服务加载数据库
技术渣,大家将就着看 首先我们需要一个xml数据保存到数据库,这里我从QQ下面找到一个loclist.xml文件 <CountryRegion Name="中国" Code= ...
- [转载]再次谈谈easyui datagrid 的数据加载
这篇文章只谈jQuery easyui datagrid 的数据加载,因为这也是大家谈论最多的内容.其实easyui datagrid加载数据只有两种方式:一种是ajax加载目标url返回的json数 ...
- RE:通过移动端滑动手势实现数据加载
背景: 基于要尝试的移动端项目需要有一个通过上拉下滑手势达成加载不同数据的功能,其涉及到滑动手势和ajax数据加载方面的知识点.故对整个实现过程做一个记录整理.个人JS功底有限,看 ...
随机推荐
- SSM动态展示分页
这个作业属于哪个课程 2021春软件工程实践|S班(福州大学) 这个作业要求在哪里 作业具体要求 这个作业的目标 个人技术 参考文献 ... 目录 技术概述 技术详述 问题和解决过程 总结 参考文献 ...
- PyCharm 2020.1 激活教程
本文内容皆为作者原创,如需转载,请注明出处:https://www.cnblogs.com/xuexianqi/p/14967434.html 免责声明:本方法只做学习研究之用,不得用于商业用途 若经 ...
- ShardingSphere 看这一篇就够了
1.什么是shardingSphere Apache ShardingSphere 是一套开源的分布式数据库中间件解决方案组成的生态圈,它由 JDBC.Proxy 和 Sidecar(规划中)这 ...
- UnityPlayerActivity删除后的后果
刚踩完这个坑,来说一下吧! 原因: 我因为前阵子学习了一下Unity Android交互,在这个过程中,我创建了类库,在类库里因为要用UnityPlayerActivity.java类所以便把Unit ...
- 从零开始学前端,React框架背后的核心机制和原理JSX
什么是React React是起源于Facebook的一个前端框架,用于构建用户界面的JavaScript库,Facebook用来探索一种更加高效优雅的Javascript MVC框架来架设Insta ...
- Flask(7)- request 对象
Flask 中很重要的 request 对象 浏览器访问服务端时,向服务端发送请求 Flask 程序使用 request 对象描述请求信息 当你想获取请求体.请求参数.请求头数据的时候,就需要靠 re ...
- APDU:APDU常用指令
APDU= ApplicationProtocol data unit, 是智能卡与智能卡读卡器之间传送的信息单元, (给智能卡发送的命令)指令(ISO 7816-4规范有定义) CLA INS P1 ...
- 使用Flyway来管理数据库版本
使用Flyway来管理数据库版本 Flyway是什么 Flyway是一款数据库迁移(migration)工具. 它可以帮助我们在不同环境保持数据库的同步,减少手工操作,避免数据导入的顺序错误,同时也减 ...
- 【故障公告】redis 服务器宕机引发博客站点故障
非常抱歉,今天下午 17:10~17:40 左右,由于博客系统所使用的 redis 服务器宕机,造成博客站点无法正常访问,由此给您带来很大的麻烦,请您谅解. 我们会针对这次故障改进 redis 服务器 ...
- spring boot 集成mqtt
1.pom文件中添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifact ...