vue-router 组件复用问题详解


Posted in Javascript onJanuary 22, 2018

组件系统是Vue的一个重要组成部分,它可以将一个复杂的页面抽象分解成许多小型、独立、可复用的组件,通过组合组件来组成应用程序,结合 vue-router 的路由功能将各个组件映射到相应的路由上,通过路由的变化来告诉Vue要在哪里渲染他们,实现各个组件、各个页面之间的跳转导航。

问题

使用 vue-router 切换路由时会触发组件树的更新,根据定义的路由渲染一个新的组件树,大致的切换过程是这样的:

  1. 停用并移除不需要的组件
  2. 验证切换的可行性
  3. 复用没有进行更新的组件
  4. 启用并激活新的组件

具体路由切换控制流程请参考官方文档:切换控制流水线

那 vue-router 是怎么判断某一个组件可以复用的呢? 我们看一下下面这条路由配置:

{
  path: 'post/:postId',
  name: 'post',
  component: resolve => require(['./components/Post.vue'],resolve)
}

这是通过文章ID加载对应文章页面的路由,第一次访问时, Post.vue 这个组件会被渲染到组件树中,mounted安装组件时通过文章ID获取文章内容展示到页面上,当我们访问另一篇文章时,路由参数 :postId 发生改变,按照我们的预期应该会展示新文章的内容,但是事与愿违。

我们看到的还是之前的文章,虽然路由参数已发生更改,但是 vue-router 会以为你访问的是 Post.vue 这个组件,由于之前已经渲染过该组件,所以会直接复用之前的组件,并且 不会 执行组件中的任何操作包括 mounted 之类的生命周期函数。

所以我们最终看到的还是原来组件的内容。

那要怎么才能实现我们期望的效果呢?下面介绍一种有效的解决方法

解决方法

我们可以使用 watch 侦听器来监听路由的变化情况,根据路由参数的变化来响应相应的数据,具体实现过程是这样的:

定义数据获取方法

首先定义一个获取文章的方法,根据文章ID从后台获取对应的文章信息。

methods: {
  getPost(postId) {
    this.$http.get(`/post/get_post/${postId}`).then((response) => {
      if(response.data.code === 0){
        this.post = response.data.post;
      }
    });
  }
}

监听路由

接着是在路由切换的时候判断目标组件是否是 Post.vue 组件,这里可以根据定义的路由名称 name 实现,如果是,我们就可以从路由信息中获取目标文章ID来更新组件内容。

watch: {
  '$route' (to, from) {
    if(to.name === 'post'){
      this.getPost(to.params.postId);
    }
  }
}

组件初始化

这里需要注意的是, 当组件首次被挂载到组件树上时,对路由的监听是无效的 ,这时我们需要在生命周期钩子 mounted 对组件进行初始化工作:

mounted() {
  this.getPost(this.$route.params.postId);
}

写在最后

通过上面的方法就可以实现组件内容随路由参数的变化而更新了,有效解决了 vue-router 组件复用导致路由参数失效的问题。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js弹窗代码 可以指定弹出间隔
Jul 03 Javascript
js实现动态改变字体大小代码
Jan 02 Javascript
JavaScript的原型继承详解
Feb 15 Javascript
JS实现当前页居中分页效果的方法
Jun 18 Javascript
基于JS实现密码框(password)中显示文字提示功能代码
May 27 Javascript
深入理解JS继承和原型链的问题
Dec 17 Javascript
angular分页指令操作
Jan 09 Javascript
理解javascript中的Function.prototype.bind的方法
Feb 03 Javascript
JS及JQuery对Html内容编码,Html转义
Feb 17 Javascript
Vue服务端渲染和Vue浏览器端渲染的性能对比(实例PK )
Mar 31 Javascript
vue使用自定义指令实现拖拽
Jan 29 Javascript
Vue Components 数字键盘的实现
Sep 18 Javascript
详解webpack多页面配置记录
Jan 22 #Javascript
详解html-webpack-plugin用法全解
Jan 22 #Javascript
js构造函数创建对象是否加new问题
Jan 22 #Javascript
bmob js-sdk 在vue中的使用教程
Jan 21 #Javascript
vue计算属性时v-for处理数组时遇到的一个bug问题
Jan 21 #Javascript
Angular17之Angular自定义指令详解
Jan 21 #Javascript
laravel5.3 vue 实现收藏夹功能实例详解
Jan 21 #Javascript
You might like
dedecms函数分享之获取某一栏目所有子栏目
2014/05/19 PHP
php替换字符串中间字符为省略号的方法
2015/05/04 PHP
php foreach如何跳出两层循环(详解)
2016/11/05 PHP
传递参数的标准方法(jQuery.ajax)
2008/11/19 Javascript
jQuery EasyUI API 中文文档 DateTimeBox日期时间框
2011/10/16 Javascript
点击A元素触发B元素的事件在IE8下会识别成A元素
2014/09/04 Javascript
JQuery判断radio是否选中并获取选中值的示例代码
2014/10/17 Javascript
jquery实现点击向下展开菜单项(伸缩导航)效果
2015/08/22 Javascript
浅谈js控制li标签排序问题 js调用php函数的方法
2016/10/16 Javascript
jQuery.parseHTML() 函数详解
2017/01/09 Javascript
JavaScript实现的select点菜功能示例
2017/01/16 Javascript
JS实现图片手风琴效果
2020/04/17 Javascript
基于vue的换肤功能的示例代码
2017/10/10 Javascript
Angular实现的进度条功能示例
2018/02/18 Javascript
解决layui中的form表单与button的点击事件冲突问题
2018/08/15 Javascript
详解如何解决Vue和vue-template-compiler版本之间的问题
2018/09/17 Javascript
浅谈小程序globalData的那些事儿
2019/11/01 Javascript
通过Kettle自定义jar包供javascript使用
2020/01/29 Javascript
一篇文章带你搞懂Vue虚拟Dom与diff算法
2020/08/25 Javascript
vue操作dom元素的3种方法示例
2020/09/20 Javascript
Python中用于计算对数的log()方法
2015/05/15 Python
Python中字典的基础知识归纳小结
2015/08/19 Python
简单谈谈python中的Queue与多进程
2016/08/25 Python
Python 判断文件或目录是否存在的实例代码
2018/07/19 Python
Python设计模式之桥接模式原理与用法实例分析
2019/01/10 Python
pycharm 2018 激活码及破解补丁激活方式
2020/09/21 Python
美体小铺加拿大官方网站:The Body Shop加拿大
2016/10/30 全球购物
生物有机护肤品:Aurelia Probiotic Skincare
2018/01/31 全球购物
医学毕业生自荐信
2013/10/11 职场文书
药品质量检测应届生求职信
2013/11/14 职场文书
2014年学生会生活部工作总结
2014/11/07 职场文书
学校党支部公开承诺书
2015/04/30 职场文书
飞越疯人院观后感
2015/06/09 职场文书
大学生党课感想
2015/08/11 职场文书
股东合作协议书模板2篇
2019/11/05 职场文书
Go语言空白表示符_的实例用法
2021/07/04 Golang