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 相关文章推荐
对YUI扩展的Gird组件 Part-1
Mar 10 Javascript
JavaScript prototype对象的属性说明
Mar 13 Javascript
javascript 数据类型转换(parseInt,parseFloat)
Jul 20 Javascript
简单实用的js调试logger组件实现代码
Nov 20 Javascript
Dom 学习总结以及实例的使用介绍
Apr 24 Javascript
js获取IP和PcName(IE)在vs中可用
Aug 02 Javascript
javascript检查浏览器是否支持flash的实现代码
Aug 14 Javascript
jQuery实现的图片分组切换焦点图插件
Jan 06 Javascript
ionic实现可滑动的tab选项卡切换效果
Apr 15 Javascript
React利用插件和不用插件实现双向绑定的方法详解
Jul 03 Javascript
Chart.js 轻量级HTML5图表绘制工具库(知识整理)
May 22 Javascript
微信小程序多音频播放进度条问题
Aug 28 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
关于二级目录拖拽排序的实现(源码示例下载)
2013/04/26 PHP
php 批量替换html标签的实例代码
2013/11/26 PHP
php中strtotime函数用法详解
2014/11/15 PHP
PHP中的一些常用函数收集
2015/05/26 PHP
PHP结合jQuery实现找回密码
2015/07/22 PHP
PHP查询大量数据内存耗尽问题的解决方法
2016/10/28 PHP
Yii框架常见缓存应用实例小结
2019/09/09 PHP
JS控件autocomplete 0.11演示及下载 1月5日已更新
2007/01/09 Javascript
JS trim去空格的最佳实践
2011/10/30 Javascript
3分钟写出来的Jquery版checkbox全选反选功能
2013/10/23 Javascript
jquery按回车提交数据的代码示例
2013/11/05 Javascript
jQuery平滑旋转幻灯片特效代码分享
2015/09/07 Javascript
JavaScript中rem布局在react中的应用
2015/12/09 Javascript
js 弹出对话框(遮罩)透明,可拖动的简单实例
2016/07/11 Javascript
详解js中Json的语法与格式
2016/11/22 Javascript
js实现旋转木马效果
2017/03/17 Javascript
利用ES6实现单例模式及其应用详解
2017/12/09 Javascript
VUE解决微信签名及SPA微信invalid signature问题(完美处理)
2019/03/29 Javascript
js实现页面图片消除效果
2020/03/24 Javascript
vue实现购物车列表
2020/06/30 Javascript
[50:58]2018DOTA2亚洲邀请赛3月29日 小组赛A组OpTic VS Newbee
2018/03/30 DOTA
Python 装饰器使用详解
2017/07/29 Python
Python实现检测文件MD5值的方法示例
2018/04/11 Python
python编写简单端口扫描器
2019/09/04 Python
python 两种方法修改文件的创建时间、修改时间、访问时间
2020/09/26 Python
美国孩之宝玩具官网:Hasbro Pulse
2019/06/24 全球购物
G-Form护具官方网站:美国运动保护装备
2019/09/04 全球购物
时尚孕妇装:HATCH Collection
2019/09/24 全球购物
英语专业毕业生自荐信
2013/10/28 职场文书
投标邀请书范文
2014/01/31 职场文书
企业业务员岗位职责
2014/03/14 职场文书
自强之星事迹材料
2014/05/12 职场文书
选秀节目策划方案
2014/06/06 职场文书
要账委托书范本
2014/09/15 职场文书
篮球赛闭幕式主持词
2015/07/03 职场文书
OpenCV 图像梯度的实现方法
2021/07/25 Python