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 相关文章推荐
artDialog 4.1.5 Dreamweaver代码提示/补全插件 附下载
Jul 31 Javascript
String.prototype实现的一些javascript函数介绍
Nov 22 Javascript
js点击按钮实现水波纹效果代码(CSS3和Canves)
Sep 15 Javascript
node.js中的事件处理机制详解
Nov 26 Javascript
基于vue的fullpage.js单页滚动插件
Mar 20 Javascript
JS操作xml对象转换为Json对象示例
Mar 25 Javascript
浅谈Angular路由守卫
Aug 26 Javascript
swiper自定义分页器使用方法详解
Sep 14 Javascript
ReactNative实现Toast的示例
Dec 31 Javascript
微信小程序与公众号卡券/会员打通的问题
Jul 25 Javascript
axios解决高并发的方法:axios.all()与axios.spread()的操作
Nov 09 Javascript
何时使用Map来代替普通的JS对象
Apr 29 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
PHP 中英文混合排版中处理字符串常用的函数
2007/04/12 PHP
php empty函数判断mysql表单是否为空
2010/04/12 PHP
用mysql_fetch_array()获取当前行数据的方法详解
2013/06/05 PHP
php去除换行(回车换行)的三种方法
2014/03/26 PHP
PHP中preg_match正则匹配中的/u、/i、/s含义
2015/04/17 PHP
php封装好的人民币数值转中文大写类
2015/12/20 PHP
php排序算法实例分析
2016/10/17 PHP
PHP实现类似于C语言的文件读取及解析功能
2017/09/01 PHP
JavaScript 异步调用框架 (Part 5 - 链式实现)
2009/08/04 Javascript
js常用自定义公共函数汇总
2014/01/15 Javascript
js获取某元素的class里面的css属性值代码
2014/01/16 Javascript
一个html5播放视频的video控件只支持android的默认格式mp4和3gp
2014/05/08 Javascript
理运用命名空间让js不产生冲突避免全局变量的泛滥
2014/06/15 Javascript
jQuery实现滑动页面固定顶部显示(可根据显示位置消失与替换)
2015/10/28 Javascript
谈谈JavaScript中浏览器兼容问题的写法小议
2016/12/17 Javascript
微信小程序 ES6Promise.all批量上传文件实现代码
2017/04/14 Javascript
vue.js 左侧二级菜单显示与隐藏切换的实例代码
2017/05/23 Javascript
js中getBoundingClientRect的作用及兼容方案详解
2018/02/01 Javascript
[52:10]LGD vs Optic Supermajor小组赛D组胜者组决赛 BO3 第二场 6.3
2018/06/04 DOTA
python使用calendar输出指定年份全年日历的方法
2015/04/04 Python
python 设置文件编码格式的实现方法
2017/12/21 Python
如何使用Python的Requests包实现模拟登陆
2018/04/27 Python
Python实现的多项式拟合功能示例【基于matplotlib】
2018/05/15 Python
python逆序打印各位数字的方法
2018/06/25 Python
python dlib人脸识别代码实例
2019/04/04 Python
python实现从本地摄像头和网络摄像头截取图片功能
2019/07/11 Python
pycharm设置鼠标悬停查看方法设置
2019/07/29 Python
Python开发之身份证验证库id_validator验证身份证号合法性及根据身份证号返回住址年龄等信息
2020/03/20 Python
Python使用sqlite3模块内置数据库
2020/05/07 Python
搭建pypi私有仓库实现过程详解
2020/11/25 Python
《满井游记》教学反思
2014/02/26 职场文书
廉洁使者实施方案
2014/03/29 职场文书
结婚保证书范文
2014/04/29 职场文书
企业领导对照检查材料
2014/08/20 职场文书
小学毕业感言200字
2015/07/30 职场文书
优秀党员主要事迹范文
2015/11/05 职场文书