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实现多选项切换导航菜单的方法
Feb 06 Javascript
JavaScript正则表达式之multiline属性的应用
Jun 16 Javascript
jQuery实现鼠标经过时出现隐藏层文字链接的方法
Oct 12 Javascript
javascript Slip.js实现整屏滑动的手机网页
Nov 25 Javascript
深入浅析knockout源码分析之订阅
Jul 12 Javascript
原生js实现tab选项卡切换
Mar 23 Javascript
JavaScript数组去重的几种方法效率测试
Oct 23 Javascript
详解AngularJS1.6版本中ui-router路由中/#!/的解决方法
May 22 Javascript
解决Vue编译时写在style中的路径问题
Sep 21 Javascript
javascript实现Emrips反质数枚举的示例代码
Dec 06 Javascript
LayUI表格批量删除方法
Aug 15 Javascript
js验证账户名是否重复
May 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 字符串编码截取函数(兼容utf-8和gb2312)
2009/05/02 PHP
MySQL连接数超过限制的解决方法
2011/07/17 PHP
php数组函数序列之array_intersect() 返回两个或多个数组的交集数组
2011/11/10 PHP
ie与session丢失(新窗口cookie丢失)实测及解决方案
2013/07/15 PHP
php生成RSS订阅的方法
2015/02/13 PHP
分享3个php获取日历的函数
2015/09/25 PHP
PHP给源代码加密的几种方法汇总(推荐)
2018/02/06 PHP
使用PHP访问RabbitMQ消息队列的方法示例
2018/06/06 PHP
jquery异步循环获取功能实现代码
2010/09/19 Javascript
一个简单的全屏图片上下打开显示网页效果示例
2014/07/08 Javascript
jQuery中position()方法用法实例
2015/01/16 Javascript
javascript中setTimeout使用指南
2015/07/26 Javascript
基于JavaScript实现瀑布流效果
2017/03/29 Javascript
jQuery中.attr()和.data()的区别分析
2017/09/03 jQuery
iconfont的三种使用方式详解
2018/08/05 Javascript
javascript 高级语法之继承的基本使用方法示例
2019/11/11 Javascript
JS实现滑动导航效果
2020/01/14 Javascript
JS中的继承操作实例总结
2020/06/06 Javascript
JS获取当前时间戳方法解析
2020/08/29 Javascript
Vue实现购物小球抛物线的方法实例
2020/11/22 Vue.js
[54:10]完美世界DOTA2联赛PWL S2 Magma vs FTD 第二场 11.29
2020/12/03 DOTA
python使用电子邮件模块smtplib的方法
2016/08/28 Python
浅析使用Python操作文件
2017/07/31 Python
详解Django rest_framework实现RESTful API
2018/05/24 Python
ubuntu17.4下为python和python3装上pip的方法
2018/06/12 Python
Python2和Python3的共存和切换使用
2019/04/12 Python
在python中做正态性检验示例
2019/12/09 Python
巴西补充剂和维生素购物网站:Natue
2019/06/17 全球购物
四下基层实施方案
2014/03/28 职场文书
2014年学校教学工作总结
2014/12/06 职场文书
2015年幼儿园新年寄语
2014/12/08 职场文书
2014年学校禁毒工作总结
2014/12/23 职场文书
行政前台岗位职责
2015/04/16 职场文书
毕业实习单位意见
2015/06/04 职场文书
2016大学生党校学习心得体会
2016/01/06 职场文书
Python 实现Mac 屏幕截图详解
2021/10/05 Python