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 MD4
Dec 20 Javascript
Jquery模仿Baidu、Google搜索时自动补充搜索结果提示
Dec 26 Javascript
js中array的sort()方法使用介绍
Feb 20 Javascript
根据配置文件加载js依赖模块
Dec 29 Javascript
JavaScript随机生成信用卡卡号的方法
Apr 07 Javascript
浅谈javascript中for in 和 for each in的区别
Apr 23 Javascript
jQuery无刷新切换主题皮肤实例讲解
Oct 21 Javascript
jQuery插件开发精品教程让你的jQuery提升一个台阶
Jan 27 Javascript
Bootstrap时间选择器datetimepicker和daterangepicker使用实例解析
Sep 17 Javascript
原生Javascript和jQuery做轮播图简单例子
Oct 11 Javascript
bootstrap select下拉搜索插件使用方法详解
Nov 23 Javascript
微信小程序中添加客服按钮contact-button功能
Apr 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程序员最常犯的11个MySQL错误小结
2010/11/20 PHP
php中is_null,empty,isset,unset 的区别详细介绍
2013/04/28 PHP
CodeIgniter集成smarty的方法详解
2016/05/26 PHP
用javascript实现无刷新更新数据的详细步骤 asp
2006/12/26 Javascript
JS类中定义原型方法的两种实现的区别
2007/03/08 Javascript
JS对URL字符串进行编码/解码分析
2008/10/25 Javascript
javascript继承之为什么要继承
2012/11/10 Javascript
jQuery ajax(复习)—Baidu ajax request分离版
2013/01/24 Javascript
jQuery往返城市和日期查询实例讲解
2015/10/09 Javascript
jquery获取select选中值的方法分析
2015/12/22 Javascript
Bootstrap按钮下拉菜单组件详解
2016/05/10 Javascript
js实现倒计时及时间对象
2016/11/15 Javascript
JS正则验证多个邮箱完整实例【邮箱用分号隔开】
2017/04/19 Javascript
bootstrap3 dialog 更强大、更灵活的模态框
2017/04/20 Javascript
vue2.0中vue-cli实现全选、单选计算总价格的实例代码
2017/07/18 Javascript
浅谈webpack下的AOP式无侵入注入
2017/11/12 Javascript
AngularJS动态添加数据并删除的实例
2018/02/27 Javascript
vue2.0项目实现路由跳转的方法详解
2018/06/21 Javascript
JS实现随机点名器
2020/04/12 Javascript
vue监听浏览器原生返回按钮,进行路由转跳操作
2020/09/09 Javascript
小程序实现点击tab切换左右滑动
2020/11/16 Javascript
[01:01:31]2018DOTA2亚洲邀请赛3月29日小组赛B组 Mineski VS paiN
2018/03/30 DOTA
详解numpy.meshgrid()方法使用
2019/08/01 Python
python 队列基本定义与使用方法【初始化、赋值、判断等】
2019/10/24 Python
详解移动端HTML5页面端去掉input输入框的白色背景和边框(兼容Android和ios)
2016/12/15 HTML / CSS
解决HTML5中滚动到底部的事件问题
2019/08/22 HTML / CSS
电子商务专业学生的自我鉴定
2013/11/28 职场文书
自荐信格式
2013/12/01 职场文书
服装设计师职业生涯规划范文
2014/02/28 职场文书
4s店市场专员岗位职责
2014/04/09 职场文书
2014审计局领导班子民主生活会对照检查材料思想汇报
2014/09/20 职场文书
四川省传达学习贯彻党的群众路线教育实践活动总结大会精神新闻稿
2014/10/26 职场文书
写给医生的感谢信
2015/01/22 职场文书
写给同学的新学期寄语
2015/02/27 职场文书
朋友离别感言
2015/08/04 职场文书
vue中div禁止点击事件的实现
2022/04/02 Vue.js