vue router动态路由下让每个子路由都是独立组件的解决方案


Posted in Javascript onApril 24, 2018

vue-router 之动态路由

vue-router官网上面是这样说的
// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})
然后,我就这样写了:
this.$router.push({path:'manage', query: {id: 'tasklist'}})1
结果很明显,失败了。然后我就默默的再次看了一下官网,结果发现了这句话
// 命名的路由
router.push({ name: 'user', params: { userId: 123 }})
// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', params: { plan: 'private' }})
注意:如果提供了 path,params 会被忽略,上述例子中的 query 并不属于这种情况。取而代之的是下面例子的做法,你需要提供路由的 name 或手写完整的带有参数的 path:
const userId = 123
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// 这里的 params 不生效
router.push({ path: '/user', params: { userId }}) // -> /user
谨记啊,动态实现二级路由,需要先用变量保存二级路由名称(let router = 'tasklist'),然后调用this.$router.push({path: `/user/${router}`}).

下面看下vue router动态路由下让每个子路由都是独立组件的解决方案

因为 vue-router 对嵌套路由采用的是组件复用策略,这在大部分场景的确是高效的做法,但是如果遇到这种情况:

vue router动态路由下让每个子路由都是独立组件的解决方案

就是要求多个子路由共活,并且有频繁来回切换需求的话,就很希望能让每个子路由都是独立组件了,虽然可以通过监听路由切换

watch: {
   '$route'(to) {
    if (to.meta.path === '/page/buy-details') {
     this.id = to.params.id;
     this.state()
    }
   }
  },

去实时处理更新的数据,我之前一直都是这么做的,包括上面那副动图的页面,但是这真的很麻烦,要让用户切换中准确的回到切换前页面的显示状态,要考虑的东西太多,于是想出了一个解决方案:

子路由组件不涉及实际业务代码,只维护一个打开过的id列表,路由切换到这边时,判断id,没打开过的添加,通过这个列表循环出实际的子路由组件,v-show当前id的,这样就能实现每个实例都是独立的了
我按这个思路写出一个 mixins

details-page.js

export default {
 watch: {
  '$route'(to, from) {
   this.detailsLeave(from);
   this.detailsOpen(to);
  }
 },
 data() {
  return {
   pagePath: '',
   pageId: 0,
   pages: {}
  }
 },
 methods: {
  /**
   * 子页面打开触发
   * @param route
   */
  detailsOpen(route) {
   if (this.detailsPathGet(route.path) === this.pagePath) {
    if (!this.pages[route.params.id]) {
     this.$set(this.pages, route.params.id, {
      id: route.params.id,
      scrollTop: 0
     })
    }
    //路由打开 跳转滚动条
    this.pageId = route.params.id;
    this.$nextTick(()=>{
     this.$parent.$el.firstChild.scrollTop = this.pages[route.params.id].scrollTop;
    });
   }
  },
  /**
   * 路由切换触发
   * 判断离开的路由是否是当前页面,如果是则记录滚动条高度
   * @param route
   */
  detailsLeave(route) {
   if (this.detailsPathGet(route.path) === this.pagePath) {
    if (this.pages[route.params.id]) {
     //记录滚动条高度 此处针对ea-admin后台 不同的框架要记录的滚动条el不同
     this.pages[route.params.id].scrollTop = this.$parent.$el.firstChild.scrollTop ;
    }
   }
  },
  /**
   * 子页面关闭函数
   * @param id
   */
  detailsClose(id) {
   delete this.pages[id]
  },
  /**
   * 取路由不含最后一项参数的地址
   * @param path
   * @returns {string}
   */
  detailsPathGet(path) {
   const i = path.lastIndexOf('/');
   return path.substr(0, i);
  }
 },
 mounted() {
  //通过当前路由地址创建页面识别地址 注:只对path: '/user/:id' 有效 当 path: /user/:id/profile 失效
  this.pagePath = this.detailsPathGet(this.$route.path);
  //执行第一次子页面打开
  this.detailsOpen(this.$route);
  //监听标签关闭消息 此处针对ea-admin后台 不同框架监听关闭方式不同
  this.$tabs.onRemove((page, next) => {
   //收到标签关闭回调,判断关闭的是否是当前页面
   if (page._path === this.pagePath) {
    //触发子页面删除
    this.detailsClose(page.id)
   }
   next()
  })
 }
}

Details.vue

<template>
 <div>
  <your-component
    v-for="item in pages"
    :id="item.id"
    :key="item.id"
    v-show="item.id === pageId">
  </your-component>
 </div>
</template>
<script>
 import YourComponent from '';
 import detailsPage from '../mixins/details-page'
 export default {
  name: 'DetailsPage',
  components: {YourComponent},
  mixins: [detailsPage],
 }
</script>

这样子组件可以只专注处理自己的固定数据,因为组件唯一,不用再去烦恼为每个id存储视图状态了。

总结

以上所述是小编给大家介绍的vue router动态路由下让每个子路由都是独立组件的解决方案,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
JS链式调用的实现方法
Mar 07 Javascript
jQuery+ajax中getJSON() 用法实例
Dec 22 Javascript
JavaScript中constructor()方法的使用简介
Jun 05 Javascript
jquery限定文本框只能输入数字(整数和小数)
Jan 08 Javascript
使用jQuery.Qrcode插件在客户端动态生成二维码并添加自定义Logo
Sep 01 Javascript
javascript代码调试之console.log 用法图文详解
Sep 30 Javascript
js图片放大镜效果实现方法详解
Oct 28 Javascript
JavaScript数据结构之广义表的定义与表示方法详解
Apr 12 Javascript
JS中实现一个下载进度条及播放进度条的代码
Jun 10 Javascript
浅谈layer的Icon样式以及一些常用的layer窗口使用方法
Sep 11 Javascript
JS实现碰撞检测效果
Mar 12 Javascript
解决vue 使用setTimeout,离开当前路由setTimeout未销毁的问题
Jul 21 Javascript
vue+webpack实现异步加载三种用法示例详解
Apr 24 #Javascript
vue中$refs的用法及作用详解
Apr 24 #Javascript
vue实现选项卡及选项卡切换效果
Apr 24 #Javascript
Vue手把手教你撸一个 beforeEnter 钩子函数
Apr 24 #Javascript
js 图片转base64的方式(两种)
Apr 24 #Javascript
react配合antd组件实现的管理系统示例代码
Apr 24 #Javascript
详解开发react应用最好用的脚手架 create-react-app
Apr 24 #Javascript
You might like
用session做客户验证时的注意事项
2006/10/09 PHP
php 分页函数multi() discuz
2009/06/21 PHP
深入php中var_dump方法的使用详解
2013/06/24 PHP
ThinkPHP静态缓存简单配置和使用方法详解
2016/03/23 PHP
php+mysql+ajax实现单表多字段多关键词查询的方法
2017/04/15 PHP
php 中htmlentities导致中文无法查询问题
2018/09/10 PHP
JavaScript使用focus()设置焦点失败的解决方法
2014/09/03 Javascript
AngularJS HTML编译器介绍
2014/12/06 Javascript
js实现class样式的修改、添加及删除的方法
2015/01/20 Javascript
手机开发必备技巧:javascript及CSS功能代码分享
2015/05/25 Javascript
Javascript日期格式化format函数的使用方法
2016/08/30 Javascript
javascript的函数劫持浅析
2016/09/26 Javascript
js 模仿锚点定位的实现方法
2016/11/19 Javascript
jQuery加载及解析XML文件的方法实例分析
2017/01/22 Javascript
详谈js中数组(array)和对象(object)的区别
2017/02/27 Javascript
React中jquery引用的实现方法
2017/09/12 jQuery
一步步教你利用Canvas对图片进行处理
2017/09/19 Javascript
Angular2监听页面大小变化的解决方法
2017/10/09 Javascript
nodejs基于mssql模块连接sqlserver数据库的简单封装操作示例
2018/01/05 NodeJs
微信小程序自定义波浪组件使用方法详解
2019/09/21 Javascript
JavaScript判断浏览器版本的方法
2019/11/03 Javascript
使用vue-cli4.0快速搭建一个项目的方法步骤
2019/12/04 Javascript
详解ES6 CLASS在微信小程序中的应用实例
2020/04/24 Javascript
[01:39:04]DOTA2-DPC中国联赛 正赛 SAG vs CDEC BO3 第二场 2月1日
2021/03/11 DOTA
python线程池的实现实例
2013/11/18 Python
Python中的__new__与__init__魔术方法理解笔记
2014/11/08 Python
Python3实现从指定路径查找文件的方法
2015/05/22 Python
用Python将动态GIF图片倒放播放的方法
2016/11/02 Python
TensorFlow实现模型评估
2018/09/07 Python
Python如何定义接口和抽象类
2020/07/28 Python
详解pycharm连接远程linux服务器的虚拟环境的方法
2020/11/13 Python
英国体育器材进口商店:UK Sport Imports
2017/03/14 全球购物
西安当代医院管理研究院笔试题
2015/12/11 面试题
护士个人总结范文
2015/02/13 职场文书
总经理司机岗位职责
2015/04/10 职场文书
SpringBoot详解自定义Stater的应用
2022/07/15 Java/Android