一步一步学习Vue(六)
本篇继续介绍vue-router,我们需要要完成这样个demo:《分页显示文章列表》;这里我们以博客园首页列表为例简化处理:

按照上图框选所示,简单分为蓝色部分文章组件(ArticleItemComponent),橙色框选部分列表组件(ArticleListComponent);分页部分我们就简单通过router-link指令构建满足演示即可,我们的代码实现逻辑:
1、列表组件初始化数据,传递给文章组件进行渲染
2、路由改变时重新初始化列表组件,更新数据
请看我们的第一版代码:
<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>demo2</title>
<script src="https://cdn.bootcss.com/vue/2.4.1/vue.js"></script>
<script src="https://cdn.bootcss.com/vue-router/2.7.0/vue-router.js"></script>
<style>
.active{
color: red;
}
</style>
</head> <body>
<div id="app">
<router-link v-for="n in [1,2,3,4,5,6,7,8]" :to="{name:'page',params:{num:n}}" :key="n"> {{n}} </router-link>
<div>
<router-view>
</router-view>
</div> </div> <script>
var fakeData = [];
(function () {
for (var i = 0; i < 45; i++) {
fakeData.push({
id: i + 1,
title: `一步一步学习Vue (${i})`,
desc: `一步一步学习Vue---正文部分 (${i})---正文结束`,
readcount: parseInt(Math.random() * 1000)
})
}
})(); var ArticleItemComponent = {
template: `
<ul class="article-item">
<li>{{item.readcount}}</li>
<li>{{item.title}}</li>
<li>{{item.desc}}</li>
</ul>
`,
props: ['item']
} var ArticleListComponent = {
template: `
<div class="article-list">
<article-item v-for="item in articleList" :item="item" :key="item.id"></article-item>
</div>
`,
data: function () {
return {
articleList: []
}
},
created: function () {
this.activePagedData(); }, methods: {
activePagedData: function () {
var index = this.$route.params.num;
//假定每页五条数据
var start = (index - 1) * 5,
end = index * 5;
this.articleList = fakeData.slice(start, end);
}
}, components: {
'article-item': ArticleItemComponent
}
} var router = new VueRouter({
linkActiveClass:'active',
routes: [
{ name: 'page', path: '/page/:num', component: ArticleListComponent }
]
}); var app = new Vue({
router: router
}).$mount("#app");
</script>
</body> </html>
路由的配置方式上一篇文章中已经做过介绍,这里陌生的部分在于ArticleListComponent中的created的使用,一个vue实例被生成后调用这个函数。vue实例被生成后还要绑定到某个html元素上,之后还要进行编译,然后再插入到document中。每一个阶段都会有一个钩子函数,方便开发者在不同阶段处理不同逻辑;其它钩子函数我们在使用的时候会继续介绍。一般可以在created函数中调用ajax等来获取页面初始化所需的数据。
双击运行,效果如下图所示:

我们发现,就在第一次初始化的时候,文章列表正常显示出来了,但是后面路由的切换操作,并没有引起组件的更新或者说数据的更新?这是什么原因呢?其实在vue-router会最大的限度的重用组件,也就是说当page/1 and page/2这两个路径之间切换的时候,vue-router发现映射的是同一个组件,那么vue-router就会重用该组件,而不会重新创建它,因为比起销毁再创建,复用则显得更加高效,所以组件的created钩子函数就不会被执行,导致数据不会更新,从而出现上图的结果;对于上述现象vue-router也给我们提供了解决方式,上文提到了在vue-router启用之后,$route会被注入到任何组件,那么我们就可以监听$roue组件的变化来实现组件更新,基于此,请看我们的第二版代码(请看绿色部分)
//....省略其它代码
var ArticleListComponent = {
template: `
<div class="article-list">
<article-item v-for="item in articleList" :item="item" :key="item.id"></article-item>
</div>
`,
data: function () {
return {
articleList: []
}
},
created: function () {
this.activePagedData(); }, methods: {
activePagedData: function () {
var index = this.$route.params.num;
//假定每页五条数据
var start = (index - 1) * 5,
end = index * 5;
this.articleList = fakeData.slice(start, end);
}
}, watch: {
'$route': function () {
this.activePagedData(); }
}, components: {
'article-item': ArticleItemComponent
}
}
//......省略其它
保存后刷新,效果应该是这样的:

这个是一个不大不小的坑,而且这种使用场景我们在实际生产中也很常见,当你发现路由变化的时候,组件数据未更新,可以考虑由于组件重用导致的生命周期钩子未执行的情况,当然解决方式也不止这一种,在vue-router 2.2+中也增加了钩子函数同样能解决问题。而且通过watch方式有点侵入,感觉和在angular中使用watch类似,个人不推荐这种写法;我们简单修改下我们程序,作为本篇代码的最后一版本:
var ArticleListComponent = {
template: `
<div class="article-list">
<article-item v-for="item in articleList" :item="item" :key="item.id"></article-item>
</div>
`,
data: function () {
return {
articleList: []
}
},
created: function () {
var index=this.$route.params.num;
this.activePagedData(index);
},
methods: {
activePagedData: function (index) {
////假定每页五条数据
var start = (index - 1) * 5,
end = index * 5;
this.articleList = fakeData.slice(start, end);
}
},
// watch: {
// '$route': function () {
// this.activePagedData();
// }
// },
beforeRouteUpdate: function (to, from, next) {
var index=to.params.num;
this.activePagedData(index);
next();
},
components: {
'article-item': ArticleItemComponent
}
}
保存后刷新页面,可以发现效果和上图一致。
小结:今天就到这里吧,主要讲了一个知识点,如何处理vue'-router导致的组件重用问题,组件重用很多场景下提供了很好的性能指标,毕竟操作dom的代价是很大的,但是总要解决类似上述场景的问题,虽然是一个很小的知识点,但值得单独放一篇着重说明一下,下一篇会讲述生命周期(牵扯到组件生命周期和路由生命周期),敬请期待。
本篇完整代码:
<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>demo2</title>
<script src="https://cdn.bootcss.com/vue/2.4.1/vue.js"></script>
<script src="https://cdn.bootcss.com/vue-router/2.7.0/vue-router.js"></script>
<style>
.active {
color: red;
}
</style>
</head> <body>
<div id="app">
<router-link v-for="n in [1,2,3,4,5,6,7,8]" :to="{name:'page',params:{num:n}}" :key="n"> {{n}} </router-link>
<div>
<router-view>
</router-view>
</div> </div> <script>
var fakeData = [];
(function () {
for (var i = 0; i < 45; i++) {
fakeData.push({
id: i + 1,
title: `一步一步学习Vue (${i})`,
desc: `一步一步学习Vue---正文部分 (${i})---正文结束`,
readcount: parseInt(Math.random() * 1000)
})
}
})(); var ArticleItemComponent = {
template: `
<ul class="article-item">
<li>{{item.readcount}}</li>
<li>{{item.title}}</li>
<li>{{item.desc}}</li>
</ul>
`,
props: ['item']
} var ArticleListComponent = {
template: `
<div class="article-list">
<article-item v-for="item in articleList" :item="item" :key="item.id"></article-item>
</div>
`,
data: function () {
return {
articleList: []
}
},
created: function () {
var index=this.$route.params.num;
this.activePagedData(index); }, methods: {
activePagedData: function (index) {
//假定每页五条数据
var start = (index - 1) * 5,
end = index * 5;
this.articleList = fakeData.slice(start, end);
}
}, // watch: {
// '$route': function () {
// this.activePagedData(); // }
// }, beforeRouteUpdate: function (to, from, next) {
var index=to.params.num;
this.activePagedData(index);
next();
}, components: {
'article-item': ArticleItemComponent
}
} var router = new VueRouter({
linkActiveClass: 'active',
routes: [
{ name: 'page', path: '/page/:num', component: ArticleListComponent }
]
}); var app = new Vue({
router: router
}).$mount("#app");
</script>
</body> </html>
一步一步学习Vue(六)的更多相关文章
- 一步一步学习Vue(十一)
本篇继续学习vuex,还是以实例为主:我们以一步一步学Vue(四)中讲述的例子为基础,对其改造,基于vuex重构一遍,这是原始的代码: todolist.js ; (function () { var ...
- 一步一步学Vue(六)
本篇继续介绍vue-router,我们需要要完成这样个demo:<分页显示文章列表>:这里我们以博客园首页列表为例简化处理: 按照上图框选所示,简单分为蓝色部分文章组件(ArticleIt ...
- 一步一步学Vue(六)https://www.cnblogs.com/Johnzhang/p/7242640.html
一步一步学Vue(六):https://www.cnblogs.com/Johnzhang/p/7237065.html 路由 一步一步学Vue(七):https://www.cnblogs.com ...
- Vue双向绑定原理,教你一步一步实现双向绑定
当今前端天下以 Angular.React.vue 三足鼎立的局面,你不选择一个阵营基本上无法立足于前端,甚至是两个或者三个阵营都要选择,大势所趋. 所以我们要时刻保持好奇心,拥抱变化,只有在不断的变 ...
- 一步一步学Vue(四)
接上篇.上篇中给出了代码框架,没有具体实现,这一篇会对上篇定义的几个组件进行分别介绍和完善: 1.TodoContainer组件 TodoContainer组件,用来组织其它组件,这是react中推荐 ...
- 一步步带你做vue后台管理框架(二)——上手使用
系列教程<一步步带你做vue后台管理框架>第二课 github地址:vue-framework-wz 线上体验地址:立即体验 闲扯再多不会用也没白搭,这节课我来带大家直接上手框架,体验到简 ...
- 一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](六)
前言 大家好,我是Rector 又是星期五,很兴奋,很高兴,很high...啦啦啦... Rector在图享网又和大家见面啦!!!上一篇<一步一步创建ASP.NET MVC5程序[Reposit ...
- 如何一步一步用DDD设计一个电商网站(六)—— 给购物车加点料,集成售价上下文
阅读目录 前言 如何在一个项目中实现多个上下文的业务 售价上下文与购买上下文的集成 结语 一.前言 前几篇已经实现了一个最简单的购买过程,这次开始往这个过程中增加一些东西.比如促销.会员价等,在我们的 ...
- 12.Linux软件安装 (一步一步学习大数据系列之 Linux)
1.如何上传安装包到服务器 有三种方式: 1.1使用图形化工具,如: filezilla 如何使用FileZilla上传和下载文件 1.2使用 sftp 工具: 在 windows下使用CRT 软件 ...
随机推荐
- SQL Server 在Alwayson上使用内存表"踩坑"
200 ? "200px" : this.width)!important;} --> 介绍 因为线上alwayson环境的一个数据库上使用内存表.经过大概一个星期监控程序发 ...
- h5 + nginx + php 视频上传之突破文件大小受限的解决办法
一.环境: CentOS 6.8 nginx 1.8.0 php 7.0.10 二.背景 基于 nginx + php 的 h5 项目,上传视频的时候,如果视频太大,会上传失败. 三.正文 一份视频传 ...
- javaCV开发详解之4:转流器实现(也可作为本地收流器、推流器,新增添加图片及文字水印,视频图像帧保存),实现rtsp/rtmp/本地文件转发到rtmp流媒体服务器(基于javaCV-FFMPEG)
javaCV系列文章: javacv开发详解之1:调用本机摄像头视频 javaCV开发详解之2:推流器实现,推本地摄像头视频到流媒体服务器以及摄像头录制视频功能实现(基于javaCV-FFMPEG.j ...
- 用Backtrack进行渗透测试评估
Web应用程序的分析在渗透测试和漏洞评估中发挥了重要的作用.确定Web应用程序的正确信息(例如使用的插件,CMS类型等)都可以帮助测试者使用准确的漏洞来测试,能够降低整个渗透测试漏洞评估所花费的时间. ...
- 阻止Nmap的黑手
大大们办网站,首先要做的就是安全,一般黑客都会用nmap扫描我们的网站这是我们所不希望看到的一下我提供几个过滤机制,nmap是无法扫描到你的 1 #iptables -F 2 #iptables -A ...
- 11.并发包阻塞队列之LinkedBlockingQueue
在上文<10.并发包阻塞队列之ArrayBlockingQueue>中简要解析了ArrayBlockingQueue部分源码,在本文中同样要介绍的是Java并发包中的阻塞队列LinkedB ...
- jQuery 插件 的this 指向问题(实战)
daterangepicker 是一个JavaScript组件,用来选择日期. 资源直接搜索 daterangepicker 即可,当然好看的样式可以基于Bootstrap. 官网:http://ww ...
- nmon用法
一.简介 nmon是一个简单的性能监测工具,可以监测CPU.内存.网络等的使用情况.它是一个系统监视.调优.性能测试工具,它能一次性提供大量性能相关的信息. 二.安装与执行 下载地址:http://n ...
- js实现htmlToWordDemo
之前由于工作需要,需要实现将html内的一部分内容直接转为word和pdf的功能.就研究了一下方法并且实现了两个demo.今天先说一下html to word(才疏学浅,仅供交流,如有错误,请指出). ...
- Linux命令 文件备份归档恢复
cp [功能说明] 文件的备份 英文xxxx #cp命令将源文件复制到另外安全的地方,复制的文件和源文件是两个相互独立的文件,对认识一个文件的操作不影响另一个文件,但与符号链接文件中的硬链接是有区别 ...