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 手机号码合法性验证代码集合
Sep 29 Javascript
JS原型对象通俗"唱法"
Dec 27 Javascript
JavaScript实现两个Table固定表头根据页面大小自行调整
Jan 03 Javascript
JavaScript保留两位小数的2个自定义函数
May 05 Javascript
JavaScript中的pow()方法使用详解
Jun 15 Javascript
实例详解AngularJS实现无限级联动菜单
Jan 15 Javascript
理解javascript模块化
Mar 28 Javascript
基于jquery实现三级下拉菜单
May 10 Javascript
Bootstrap精简教程中秋大放送
Sep 15 Javascript
手机端实现Bootstrap简单图片轮播效果
Oct 13 Javascript
jQuery实现手势解锁密码特效
Aug 14 jQuery
vue下跨域设置的相关介绍
Aug 26 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的十大要点(上)
2009/02/04 PHP
php+mysqli事务控制实现银行转账实例
2015/01/29 PHP
php从数据库查询结果生成树形列表的方法
2015/04/17 PHP
php使用Imagick生成图片的方法
2015/07/31 PHP
重写javascript中window.confirm的行为
2012/10/21 Javascript
Javascript中自动切换焦点实现代码
2012/12/15 Javascript
一个简单的实现下拉框多选的插件可移植性比较好
2014/05/05 Javascript
详细解读AngularJS中的表单验证编程
2015/06/19 Javascript
echarts学习笔记之图表自适应问题详解
2017/11/22 Javascript
微信小程序swiper组件用法实例分析【附源码下载】
2017/12/07 Javascript
Express本地测试HTTPS的示例代码
2018/06/06 Javascript
微信小程序模拟cookie的实现
2018/06/20 Javascript
vue-cli3 从搭建到优化的详细步骤
2019/01/20 Javascript
深入了解Hybrid App技术的相关知识
2019/07/17 Javascript
vue el-table实现行内编辑功能
2019/12/11 Javascript
JS猜数字游戏实例讲解
2020/06/30 Javascript
Python使用Socket(Https)Post登录百度的实现代码
2012/05/18 Python
Python实现修改IE注册表功能示例
2018/05/10 Python
Python实现的多叉树寻找最短路径算法示例
2018/07/30 Python
Python Selenium 之关闭窗口close与quit的方法
2019/02/13 Python
Python3.5多进程原理与用法实例分析
2019/04/05 Python
python flask 如何修改默认端口号的方法步骤
2019/07/12 Python
详解pandas中iloc, loc和ix的区别和联系
2020/03/09 Python
关于keras.layers.Conv1D的kernel_size参数使用介绍
2020/05/22 Python
Python迭代器协议及for循环工作机制详解
2020/07/14 Python
CSS3模拟动画下拉菜单效果
2017/04/12 HTML / CSS
canvas实现飞机打怪兽射击小游戏的示例代码
2018/07/09 HTML / CSS
详解如何解决canvas图片getImageData,toDataURL跨域问题
2018/09/17 HTML / CSS
大学毕业生文采飞扬的自我鉴定
2013/12/03 职场文书
竞聘演讲稿范文
2014/01/12 职场文书
小学生期末评语
2014/04/21 职场文书
和谐社区口号
2014/06/19 职场文书
员工工作及收入证明
2014/10/28 职场文书
大学生自荐信范文
2015/03/05 职场文书
食堂采购员岗位职责
2015/04/03 职场文书
Python中使用Lambda函数的5种用法
2021/04/01 Python