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 相关文章推荐
javascript 函数调用规则
Aug 26 Javascript
快速排序 php与javascript的不同之处
Feb 22 Javascript
解析jQuery与其它js(Prototype)库兼容共存
Jul 04 Javascript
解析Javascript小括号“()”的多义性
Dec 03 Javascript
jQuery中prependTo()方法用法实例
Jan 08 Javascript
2则自己编写的jQuery特效分享
Feb 26 Javascript
Vuejs第七篇之Vuejs过渡动画案例全面解析
Sep 05 Javascript
JavaScript 事件流、事件处理程序及事件对象总结
Apr 01 Javascript
vue项目中jsonp跨域获取qq音乐首页推荐问题
May 30 Javascript
浅入深出Vue之组件使用
Jul 11 Javascript
Node.js控制台彩色输出的方法与原理实例详解
Dec 01 Javascript
mapboxgl区划标签避让不遮盖实现的代码详解
Jul 01 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
使用php发送有附件的电子邮件-(PHPMailer使用的实例分析)
2013/04/26 PHP
php实现阳历阴历互转的方法
2015/10/28 PHP
PHP+mysql实现的三级联动菜单功能示例
2019/02/15 PHP
由Javascript实现的页面日历
2011/11/04 Javascript
javascript四舍五入函数代码分享(保留后几位)
2013/12/10 Javascript
浅谈JavaScript中promise的使用
2017/01/11 Javascript
Angularjs 依赖压缩及自定义过滤器写法
2017/02/04 Javascript
滚动条的监听与内容随着滚动条动态加载的实现
2017/02/08 Javascript
jquery与js实现全选功能的区别
2017/06/11 jQuery
angular bootstrap timepicker TypeError提示怎么办
2017/06/13 Javascript
jquery单击文字或图片内容放大并居中显示
2017/06/23 jQuery
JavaScript中 ES6变量的结构赋值
2018/07/10 Javascript
详解vue中router-link标签所必备了解的属性
2019/04/15 Javascript
如何解决js函数防抖、节流出现的问题
2019/06/17 Javascript
vue使用自定义事件的表单输入组件用法详解【日期组件与货币组件】
2020/06/01 Javascript
vue实现导航菜单和编辑文本的示例代码
2020/07/04 Javascript
js实现圆形菜单选择器
2020/12/03 Javascript
[51:43]OG vs LGD 2018国际邀请赛淘汰赛BO3 第五场 8.26
2018/08/30 DOTA
python编程开发之textwrap文本样式处理技巧
2015/11/13 Python
python字符串循环左移
2019/03/08 Python
python3 使用openpyxl将mysql数据写入xlsx的操作
2020/05/15 Python
Java多线程实现四种方式原理详解
2020/06/02 Python
加拿大票务网站:Ticketmaster加拿大
2017/07/17 全球购物
波比布朗英国官网:Bobbi Brown英国
2017/11/13 全球购物
学术会议邀请函范文
2014/01/22 职场文书
优秀医生事迹材料
2014/02/12 职场文书
广告传媒专业应届生求职信
2014/03/01 职场文书
文化宣传方案
2014/03/13 职场文书
调查研究项目计划书
2014/04/29 职场文书
共产党员公开承诺践诺书
2014/05/28 职场文书
讲党性心得体会
2014/09/03 职场文书
初中作文评语集锦
2014/12/25 职场文书
行政司机岗位职责
2015/04/10 职场文书
2015年语文教师工作总结
2015/05/25 职场文书
IDEA2021.2配置docker如何将springboot项目打成镜像一键发布部署
2021/09/25 Java/Android
动画「进击的巨人」第86话播出感谢绘公开
2022/03/21 日漫