虽互不曾谋面,但希望能和您成为笔尖下的朋友

以读书,技术,生活为主,偶尔撒点鸡汤

不作,不敷衍,意在真诚吐露,用心分享

点击左上方,可关注本刊

标星公众号(ID:itclanCoder)

如果不知道如何操作

点击这里,标星不迷路

前言

之前有介绍过vuejs中的路由的传参及路由的props配置,对于如何配置一级路由,二级路由,对于很多同学来说,基本上没什么难度

然后在配置三级路由以上的时候,往往却没那么容易,会出现一些问题

比如:如下的,二级路由下的tab选项页,当刷新页面时,还能保持当前tab的一个状态

在切换到其他路由后,在回到当前路由,依旧能保证上一个状态等

01

配置一级二级路由

这里我使用的是基础模板:vue-admin-template,搭建的一个简易后台管理系统,在views/fontend/index.vue创建一个index.vue组件

并使用elementUI组件中的按钮样式的单选组合,实现一个tab按钮选项按钮的切换

以下是fontend/index.vue示例代码

<template><div class="wrap"><el-radio-group v-model="activeTab" @change="handleRadio"><el-radio-button v-for="item in lists" :key="item.name"  :label="item.name">{{item.name}}</el-radio-button></el-radio-group>     <router-view></router-view></div>
</template>
<script>export default {name: 'FontEnd',data(){return {activeTab: '',lists: [{// path: '/fontend/html',  name: 'html'},{// path: "/fontend/javascript",name: 'javascript'},{// path: "/fontend/css",name: "css"}]};},methods: {handleRadio(val) {this.$router.push({name: val})}},watch: {$route: {handler(val) {console.log(val);this.activeTab = val.name;},immediate:true}}}
</script>
<style lang="scss" scoped>
.wrap {padding: 30px;
}
</style>

在上面的模板代码中,使用了elementUI中的单选按钮组合组件el-radio-group,并结合v-for指令循环遍历了一个数组

同时在点击按钮时,绑定了一个change事件,使用编程式导航this.$router.push({})控制按钮路由的跳转

02

router.js路由配置

如下是router.js路由配置

import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
/* Layout */
import Layout from '@/layout'
export const constantRoutes = [{path: '/fontend',component: Layout,name:'Font',children: [{path: '',component: () => import('@/views/fontend/index'),hidden: true,redirect: '/fontend/html',// meta: { title: '前端', icon: 'nested' },children: [{path: 'html',name: 'html',component: () => import("@/views/fontend/html.vue"),meta: {title: 'html'}},{path: 'javascript',name: 'javascript',component: () => import("@/views/fontend/javascript.vue"),meta: {title: 'javascript'}},{path: 'css',name: 'css',component: () => import("@/views/fontend/css.vue"),meta: {title: 'css'}},]}],meta: {title: '前端',icon: 'nested'}},
]
const createRouter = () => new Router({// mode: 'history', // require service supportscrollBehavior: () => ({ y: 0 }),routes: constantRoutes
})
const router = createRouter()
// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
export function resetRouter() {const newRouter = createRouter()router.matcher = newRouter.matcher // reset router
}
export default router

router.js中,使用children配置了子路由,并使用异步路由懒加载形式,配置了三个子路由

03

路由不显示

页面右侧不显示,子路由未配置

04

按钮的激活状态不显示

未设置初始值

<script>export default {name: 'FontEnd',data(){return {activeTab: '', // 激活状态lists: [{// path: '/fontend/html', name: 'html'},{// path: "/fontend/javascript",name: 'javascript'},{// path: "/fontend/css",name: "css"}]};},methods: {handleRadio(val) {this.$router.push({name: val})}},watch: {$route: {handler(val) {console.log(val);this.activeTab = val.name;},immediate:true}}}
</script>

05

刷新页面,按钮不显示当前状态

未监听路由,并且设置激活状态

watch: {$route: {handler(val) {this.activeTab = val.name},immediate: true   // 一加载页面时,就自动触发上面的handler函数}
}

06

解决切换闪烁抖动问题

当切换按钮的时候,出现页面抖动

layout/components/AppMain.vue文件中,去掉transitionname='fade-transform'即可

<transition  mode="out-in"><router-view :key="key" />
</transition>

07

配置三级路由

会配置一级,二级路由,那么配置三级,四级路由..也是一样的,路由是可以进行嵌套的,使用children属性,可以无限的嵌套下去

以下是fontend/html.vue示例代码

<template><div><el-tabs v-model="activeName" @tab-click="handleClick"><el-tab-panev-for="item in tabLists":key="item.name":label="item.name":name="item.name"></el-tab-pane></el-tabs><keep-alive><router-view /></keep-alive></div>
</template>
<script>export default {name: 'Html',data() {return {activeName:'ATag',tabLists: [{name:'ATag'},{name:'BTag'},{name:'SpanTag'},],}},methods:{handleClick(val) {this.$router.push({name:val.name,})}},watch: {$route: {handler(val) {this.activeName = val.name},immediate: true}}}
</script>

上面是模板代码,使用了elementUIel-tabs组件,并使用v-for循环遍历一数组对象,同样绑定tab-click事件

使用编程式导航this.$route.push({})``,实现路由的跳转,并监听当前路由,控制当前tab`的激活状态,保持刷新页面时,仍然保持上一次的一个状态

router.js路由代码

import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
/* Layout */
import Layout from '@/layout'
export const constantRoutes = [{path: '/fontend',component: Layout,name:'Font',children: [{path: '',component: () => import('@/views/fontend/index'),hidden: true,redirect: '/fontend/a',children: [{path: 'html',name: 'html',component: () => import("@/views/fontend/html.vue"),meta: {title: 'html'},children: [   // 三级子路由{path: '/fontend/a',   // 这个是必须要写的name: 'ATag',         // 要与html.vue中的配置的name保持一一对应component: () => import("@/views/fontend/a.vue"),},{path: '/fontend/b',name: 'BTag',component: () => import("@/views/fontend/b.vue"),},{path: '/fontend/span',name: 'SpanTag',component: () => import("@/views/fontend/span.vue"),},]},{path: 'javascript',name: 'javascript',component: () => import("@/views/fontend/javascript.vue"),meta: {title: 'javascript'}},{path: 'css',name: 'css',component: () => import("@/views/fontend/css.vue"),meta: {title: 'css'}},]}],meta: {title: '前端',icon: 'nested'}},// 404 page must be placed at the end !!!{ path: '*', redirect: '/404', hidden: true }
]
const createRouter = () => new Router({// mode: 'history', // require service supportscrollBehavior: () => ({ y: 0 }),routes: constantRoutes
})
const router = createRouter()
// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
export function resetRouter() {const newRouter = createRouter()router.matcher = newRouter.matcher // reset router
}
export default router

因为a.vue,b.vue.span.vue,所属在html.vue下,所以,在router.js中,使用children配置三个子路由

  1. 注意name要与模板中的循环遍历数组对象中的name值保持一致

  2. 路由的path路径的值,是必须要写的

08

解决路由点击两下才会切换到选中激活状态

解决这个问题,监听当前下的路由就可以了的

watch: {$route: {handler(val) {this.activeName = val.name},immediate: true  // 自动触发上面的hander函数}
}

上面是通过路由的方式去实现的,但是会出现一个问题,就是二级路由tab切换的状态无法保持,怎么样控制在切换三级tab选项时,刷新页面,依旧保持二级导航切换的对应激活的状态

具体解决的办法,也可以是在路由器里面,对父级路由添加标识,这种方式非常复杂,而且代码不好维护,不建议使用这种方式

09

使用动态组件方式去渲染组件

对于一级,二级可以使用路由组件去实现,但是当出现多级的时候,路由嵌套的层级太深,只会让项目代码越来越复杂,而变得不易维护

在二级导航切换按钮,显示具体的对应的内容,就可以使用动态组件的方式去渲染

html.vue使用动态组件实现

<template><div><el-tabs v-model="activeName" @tab-click="handleClick"><el-tab-panev-for="item in tabLists":key="item.name":label="item":name="item"><!-- 使用动态组件渲染 --><component :is="activeName"></component></el-tab-pane></el-tabs></div>
</template>
<script>import ATag from "./a.vue";       // 引入组件import BTag from "./b.vue";import SpanTag from "./span.vue"export default {name: 'Html',components: {   // 注册组件ATag,BTag,SpanTag},data() {return {activeName:'ATag',tabLists: ["ATag","BTag","SpanTag"],}},mounted() {this.updateActiveTab()},methods:{updateActiveTab() {const { query } = this.$route;this.activeName = query.activeName || 'ATag'},handleClick() {const { activeName } = this;this.$router.push({name:'html',query: {activeName}})}},}
</script>

上面el-tabs组件的切换,具体显示哪个对应的组件,使用了动态组件component,并通过is属性,绑定activeName,以达到控制指定组件的显示

在逻辑代码中,点击tab时,使用query的方式,经过这样的操作后,即使刷新页面,也不会丢失,保持在当前状态下的

注意事项

使用query的方式,即使是刷新页面,也会保持当前的状态,但是若使用params的方式,刷新页面时,会丢失参数,并不会保持当前的状态,如果想要保持

那么就要结合localstorage,如下示例所示

上面是使用,动态组件的方式去渲染的

10

使用本地localStorage存储保持状态

如果不使用query方式,使用params的方式也是可以的,但若想保持状态,那么就需要结合localStorage进行使用,如下代码所示

代码上基本没有什么变化,代码上基本没有什么变化,只不过是使用了本地存储localStorage

<template><div><el-tabs v-model="activeName" @tab-click="handleClick"><el-tab-panev-for="item in tabLists":key="item.name":label="item":name="item"><component :is="activeName"></component></el-tab-pane></el-tabs></div>
</template>
<script>import ATag from "./a.vue";import BTag from "./b.vue";import SpanTag from "./span.vue"export default {name: 'Html',components: {ATag,BTag,SpanTag},data() {return {activeName:'ATag',tabLists: ["ATag","BTag","SpanTag"],}},mounted() {this.updateActiveTab()console.log(localStorage.getItem('activeName'));},methods:{updateActiveTab() {const { params } = this.$route;this.activeName = params.activeName || localStorage.getItem('activeName');},handleClick() {const { activeName } = this;localStorage.setItem('activeName',activeName);  // 设置本地存储this.$router.push({name:'html',   // 如果使用params方式,就需要使用name方式,如果是query,也可以写具体的path:'/font/html'params: {activeName}})}},}
</script>

针对这种三级或三级以上的,使用路由的方式,不是不可以,但是当路由嵌套的层次太多,就会使组件变得复杂起来

而使用动态渲染组件的方式,就极大的简化了逻辑,只需要考虑渲染显示对应的组件就可以

总结

其实,二级导航的切换,同样也是可以设计成动态组件的,具体看自己习惯用哪个,能够实现具体的业务就行,但有些情况下,设计成动态组件

明显要简单,容易得多,能够减少很多不必要的逻辑

而使用query的方式是可以保持状态的,参数会明文的出现在地止栏上,即使刷新页面,也不会丢失,而若使用params方式,想要状态不丢失,那么就要结合localStorage进行配合使用

Js中如何不借助第三个中间变量实现交换两个变量的值

2022-09-10

JS特效2-如何实现页面的前进与后退

2022-09-09

JS特效1-实现自动刷新页面

2022-09-08

关于script标签中type的使用

2022-09-07

如何利用微信视频号挣钱

2022-09-05

点个在看你最好看

点击左下角即可阅读原文

vuejs中如何实现三级路由并刷新页面时保持当前路由激活状态相关推荐

  1. Vue.JS项目中二级路由下刷新浏览器仍呈现当前路由的实现方案

    1.需求介绍: 以下介绍一下实现起来没什么疑问的需求:设备列表为一个主页,点击设备列表中的编辑按钮,进入设备信息主页面,默认打开设备配置页,点击设备状态.设备日志.固件升级,会切换下方内容. 本人对以 ...

  2. 通过setTimeout调用设置iframe src的方法导致刷新页面时弹出没有权限错误!

    通过setTimeout调用设置iframe src的方法导致刷新页面时弹出没有权限错误! 如下: Html代码 <iframe tabindex="4" id=" ...

  3. html 刷新表格数据,当我刷新页面时在html表格上重复数据

    我从数据库中选择一些数据,并试图在html表格上显示它们. 问题是,当我刷新页面时,我得到了所有在我的html表上重复的数据.我一直试图谷歌/解决这个问题,但三天没有结果.当我刷新页面时在html表格 ...

  4. 如何防止用户修改html提交,当用户刷新页面时,HTML表单被重新提交 - 我如何阻止这种情况发生?...

    当用户提交一个html表单(method ="post")后,它将它们带回到它们所在的页面(但其中一些数据已更改).如果用户刷新页面,则再次提交表单.在我的应用程序中,这可能会创建 ...

  5. 动态路由下刷新 页面空白

    前言 最近设计动态路由时,刷新页面空白.突然想起以前笔记里面记录过,翻看了下,今天得空儿分享出来. 问题描述 在全局前置守卫router.beforeEach里面加入动态路由设计时,刷新动态页面,明明 ...

  6. gin路由打开html页面,Gin(二):使用路由

    更多文章 狂点 经过上一章节的介绍,搭建一个简单的 Gin web 项目非常容易,同时也引入了一些新的概念,比如说:路由 Router. 路由是一个非常重要的概念,所有的接口都要有路由来进行管理. 请 ...

  7. 微信小程序 下拉刷新页面时的加载状态

    案发现场:在微信小程序中,用力往下拉动,页面顶部会出现一段空白的地方. 其实三个点是可以看到的.只不过默认是白色的 案例效果 1.在 app.json中 添加样式 "backgroundTe ...

  8. vue路由history模式刷新页面时页面丢失时常见的两种解决方法

    方法一: 1 2 3 4 5 6 7 8 location /{     root   /data/nginx/html;     index  index.html index.htm;     i ...

  9. 静态页中利用AJAX.NET实现无刷新页面

    一. 导言 我们知道,ASP.net应用程序事实是在服务器上运行的,用户的请求要不断地送往远程的服务器,服务器执行完本地的程序后把重新装载页面再发送客户端.所以就出现了不断刷新的问题,页面不断闪烁.用 ...

最新文章

  1. 17._5正则表达式的替换
  2. 一个简单问题引发对IEnumerable和IQueryable的思考
  3. Mysql导出函数、存储过程
  4. webflux webclient DataBufferLimitException: Exceeded limit on max bytes to buffer
  5. 7-33 地下迷宫探索 (30 分)(思路加详解)
  6. P2050-[NOI2012]美食节【费用流,动态连边】
  7. 认识CUBA平台的CLI
  8. html二级下拉菜单模板,基于jQuery实现二级下拉菜单效果
  9. Kotlin入门教程——目录索引
  10. 数据分析师熬夜整理:最全「零售业」数据指标和使用技巧
  11. Matlab模拟液压缸运动,基于MATLAB-simulink的液压系统动态仿真(1).pptx
  12. 64位系统中32位的打印服务器,windows10-64位系统如何连接window7-32位共享打印机
  13. 河南省第二届“金盾信安杯”网络安全大赛 WriteUp Crypto+Misc
  14. 英语手记——持续更新
  15. 鼠标变成方块而不是竖线
  16. 如何用requests获取百度网站的图片资源
  17. 全国青少年科技创新大赛全国青少年信息学奥林匹克系列比赛(大赛系列第12期)
  18. 举个栗子!Tableau 技巧(113):在工作表中嵌入可切换网页
  19. cocos2dx 背包界面的实现
  20. 申请微信公众号的一些流程和注意

热门文章

  1. ZigBee Neighbor Table 邻居表
  2. 如何运用Common Neighbor方法进行链路预测
  3. 使用体系结构权衡分析法(ATAM)对两种体系结构进行评估
  4. 新手带项目那些事儿(0.15-1.07)
  5. 《辉煌优配》放量大涨,A股成交额重回万亿!PCB板块继续领跑
  6. ups属于计算机设备吗,ups电源属于什么设备?ups电源的分类
  7. 三个臭皮匠浅谈xss获取用户cookie的安全漏洞
  8. leanCloud环境搭建
  9. SOLIDWORKS如何快速生成材料明细表
  10. 2019何凯文五夜十篇