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各种复制代码收集
Sep 20 Javascript
javascript函数以及基础写法100多条实用整理
Jan 13 Javascript
jQuery实现视频作为全屏幕背景
Dec 18 Javascript
详解Javascript继承的实现
Mar 25 Javascript
详解用vue.js和laravel实现微信授权登陆
Jun 23 Javascript
Vue单页式应用(Hash模式下)实现微信分享的实例
Jul 21 Javascript
react学习笔记之state以及setState的使用
Dec 07 Javascript
基于Vue、Vuex、Vue-router实现的购物商城(原生切换动画)效果
Jan 09 Javascript
小程序组件之仿微信通讯录的实现代码
Sep 12 Javascript
JS Generator 函数的含义与用法实例总结
Apr 08 Javascript
JQuery事件冒泡和默认行为代码实例
May 13 jQuery
关于JavaScript 中 if包含逗号表达式
Nov 27 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下关于中英数字混排的字符串分割问题
2010/04/06 PHP
php中mysql操作buffer用法详解
2015/03/19 PHP
php实现只保留mysql中最新1000条记录
2015/06/18 PHP
joomla实现注册用户添加新字段的方法
2016/05/05 PHP
Laravel中GraphQL接口请求频率实战记录
2020/09/01 PHP
在你的网页中嵌入外部网页的方法
2007/04/02 Javascript
jQuery获得页面元素的绝对/相对位置即绝对X,Y坐标
2014/03/06 Javascript
纯js代码实现未知宽高的元素在指定元素中垂直水平居中显示
2015/09/12 Javascript
分享我对JS插件开发的一些感想和心得
2016/02/04 Javascript
Nodejs Stream 数据流使用手册
2016/04/17 NodeJs
Javascript中获取浏览器类型和操作系统版本等客户端信息常用代码
2016/06/28 Javascript
微信小程序开发之map地图实现教程
2017/06/08 Javascript
跨域请求两种方法 jsonp和cors的实现
2018/11/11 Javascript
用Cordova打包Vue项目的方法步骤
2019/02/02 Javascript
Python重新引入被覆盖的自带function
2014/07/16 Python
Python实现从订阅源下载图片的方法
2015/03/11 Python
Python读写文件方法总结
2015/06/09 Python
深入解析Python中的__builtins__内建对象
2016/06/21 Python
python批量设置多个Excel文件页眉页脚的脚本
2018/03/14 Python
解决seaborn在pycharm中绘图不出图的问题
2018/05/24 Python
python爬虫之线程池和进程池功能与用法详解
2018/08/02 Python
PyQt5实现类似别踩白块游戏
2019/01/24 Python
python实现雪花飘落效果实例讲解
2019/06/18 Python
python 默认参数相关知识详解
2019/09/18 Python
Python实现图像的垂直投影示例
2020/01/17 Python
Django-xadmin后台导入json数据及后台显示信息图标和主题更改方式
2020/03/11 Python
Python线程协作threading.Condition实现过程解析
2020/03/12 Python
python中str内置函数用法总结
2020/12/27 Python
CSS3制作苹果风格键盘特效
2015/02/26 HTML / CSS
Mountain Warehouse德国官网:英国户外零售商
2019/08/11 全球购物
若通过ObjectOutputStream向一个文件中多次以追加方式写入object,为什么用ObjectInputStream读取这些object时会产生StreamCorruptedException?
2016/10/17 面试题
Java语言的优势
2015/01/10 面试题
计算机网络专业个人的自我评价
2013/10/17 职场文书
保护环境倡议书
2014/04/14 职场文书
商务英语邮件开头问候语
2015/11/10 职场文书
python数据库批量插入数据的实现(executemany的使用)
2021/04/30 Python