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 15 Javascript
JQuery中html()方法使用不当带来的陷阱
Apr 07 Javascript
JS对象转换为Jquery对象示例
Jan 26 Javascript
javascript的document.referrer浏览器支持、失效情况总结
Jul 18 Javascript
JS动态创建元素的两种方法
Apr 20 Javascript
为vue-router懒加载时下载js的过程中添加loading提示避免无响应问题
Apr 03 Javascript
js中的reduce()函数讲解
Jan 18 Javascript
javascript触发模拟鼠标点击事件
Jun 26 Javascript
如何在postman测试用例中实现断言过程解析
Jul 09 Javascript
Vue.js原理分析之nextTick实现详解
Sep 07 Javascript
微信小程序调用后台service教程详解
Nov 06 Javascript
canvas实现贪食蛇的实践
Feb 15 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中session与cookie的比较
2015/01/27 PHP
懒就要懒到底——鼠标自动点击(含时间判断)
2007/02/20 Javascript
jQuery 学习第五课 Ajax 使用说明
2010/05/17 Javascript
jQuery的.live()和.die() 使用介绍
2011/09/10 Javascript
JS实现Enter键跳转及控件获得焦点
2013/08/12 Javascript
js跨浏览器实现将字符串转化为xml对象的方法
2013/09/25 Javascript
当前流行的JavaScript代码风格指南
2014/09/10 Javascript
JavaScript判断数组是否包含指定元素的方法
2015/07/01 Javascript
javascript中mouseover、mouseout使用详解
2015/07/19 Javascript
JS+CSS实现闪烁字体效果代码
2016/04/05 Javascript
41个Web开发者必须收藏的JavaScript实用技巧
2016/07/22 Javascript
json定义及jquery操作json的方法
2016/09/29 Javascript
微信小程序 wx.request(OBJECT)发起请求详解
2016/10/13 Javascript
轻松理解vue的双向数据绑定问题
2017/10/30 Javascript
vue.js 底部导航栏 一级路由显示 子路由不显示的解决方法
2018/03/09 Javascript
layui实现数据分页功能
2019/07/27 Javascript
在VUE中实现文件下载并判断状态的方法
2019/11/08 Javascript
vue data变量相互赋值后被实时同步的解决步骤
2020/08/05 Javascript
使用Vue实现一个树组件的示例
2020/11/06 Javascript
python编程嵌套函数实例代码
2018/02/11 Python
Python打印输出数组中全部元素
2018/03/13 Python
Python的matplotlib绘图如何修改背景颜色的实现
2019/07/16 Python
python用match()函数爬数据方法详解
2019/07/23 Python
基于python 微信小程序之获取已存在模板消息列表
2019/08/05 Python
python实现录屏功能(亲测好用)
2020/03/02 Python
详解Pycharm与anaconda安装配置指南
2020/08/25 Python
python链表类中获取元素实例方法
2021/02/23 Python
AmazeUI 面板的实现示例
2020/08/17 HTML / CSS
ghd官网:英国ghd直发器品牌
2018/05/04 全球购物
Rosetta Stone官方网站:语言学习
2019/01/05 全球购物
优秀员工个人的自我评价
2013/11/29 职场文书
创先争优制度
2014/01/21 职场文书
发展部经理职责规定
2014/02/22 职场文书
监察局领导班子四风问题整改措施思想汇报
2014/10/05 职场文书
第二批党的群众路线教育实践活动个人整改方案
2014/10/31 职场文书
maven依赖的version声明控制方式
2022/01/18 Java/Android