话说昨天说完首页了,那今天就来说一下列表页。
列表页其实很简单,主要就是在首页点击某个类别的按钮就跳转到该列表页,展现该类别的所有影片简介。很显然,四个类别是可以利用同一个组件的,只是渲染的数据有所不同。我们要做的就是根据在首页点击的按钮传入不同的参数,比如1,2,3,4分别代表四个类别,而在列表页就获取这个参数并向服务器请求该类别的数据。
我们在前面做轮播组件的时候给组件绑定了一个跳转事件:
<div class='checkMore'><a @click='goToCheckMore'>查看更多></a></div>
在该组件的data中注册一个etype变量用来保存当前组件所展示的类型,而etype就是从父组件传过来的数据中获取的。
this.etype = this.movies[0][0].etype;
然后点击跳转按钮就会触发相应的方法。
goToCheckMore:function(){
this.$router.push({path:'/seeAllItem',query:{type:this.etype}});
}
在详细列表页获取该参数即可。
this.etype = this.$route.query.type;
还有一个问题,当列表页中的内容有很多条时我们不可能一下子全部渲染出来吧,所以我就考虑用分页。
分页怎么实现:
在列表页的data中我设置了一个变量page用来储存当前所展现的页数,初始为1,然后在created钩子中请求第一页数据。
created:function(){
this.etype = this.$route.query.type;
var _this = this;
this.$axios.post('/api/film/getAllItem',{'etype':_this.$route.query.type,page:this.page}).then(function( res ){
_this.itemList = res.data;
_this.page++; //注意每次请求获得数据了就把page自增一,如果请求返回结果没有数据说明没有更多数据就不自增
}).catch(function(err){
console.log(err);
});
}
这样第一次进入页面时就会展现前几条数据。
然后绑定一个事件监听是否耍到底部了,如果刷到底部了就触发请求获取下面几条数据。
mounted:function(){
window.addEventListener('scroll',this.loadMore);
}
loadMore:function(){
var top = window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop; //被卷起部分的高度
var windowHeight = document.documentElement.clientHeight; //窗口大小
var totalHeight = document.documentElement.scrollHeight; //内容总高度
if(top+windowHeight >= totalHeight){ //已到达底部
this.isLoadingMore = true;
this.noMore = false;
var _this = this;
this.$axios.post('/api/film/getAllItem',{'etype':_this.$route.query.type,page:this.page}).then(function( res ){
if(res.data=='-1'){ //没有更多数据可加载
_this.isLoadingMore = false;
_this.noMore = true;
}else{ //服务器返回了下一页的数据
_this.isLoadingMore = false;
_this.noMore = false;
_this.itemList = _this.itemList.concat(res.data); //将加载的更多数据追加到数组中
_this.page++; //因为不知道是否还有更多数据所以page++,下次请求时就是请求下一页啦
}
}).catch(function(err){
console.log(err);
});
}
}
最后别忘了在离开页面之前去掉绑定事件,不然它绑定的是全局事件,在各个页面都会触发的。
beforeDestroy:function(){
window.removeEventListener('scroll',this.loadMore);
}
然后数据库那边怎么查询的:
router.post('/getAllItem',function( request , response ){
var type = request.body.etype; //请求要获取的影片类型
var page = (request.body.page-1)*3; //当前请求页数,因为我设定的是每次请求三条所以是*3,数据库索引是从0开始的所以要-1
var queryGetAll = $sql.film.query_all_item;
conn.query(queryGetAll,[type,page],function( err , result ){
if(err){
console.log(err);
}
if(result[0]!==undefined){
response.send(result);
}else{
response.send('-1');
}
});
});
query_all_item:'select * from entertainment where etype = ? order by eno desc limit ?,3',
order by desc就是降序排序,也就是从后面的记录往前面查找,找到的就是最新的,limit?,3就是查找从?开始的三个数据。
然后还有最后一个问题就是,我们从列表页点击某一部影片查看它的详细信息之后是有一个按钮可以返回的,设想一下我们千辛万苦翻了几十页之后点击查看某一部影片,返回该页面又是从第一条看起,是不是很不爽?所以就要把这页缓存起来。
如何利用vue的keep-alive缓存呢。
我们在入口组件用路由router-link渲染某一组件的部分设置keep-alive
<keep-alive> <transition :name='slideto'> <router-view v-if='$route.meta.keepAlive' class='main-view'></router-view> </transition> </keep-alive>
<transition :name='slideto'> <router-view v-if='!$route.meta.keepAlive' class='main-view'></router-view></transition>
然后在router.js中把不想缓存的页面的meta{keeplive:false},如果想缓存就设为true。
在列表页中,每当路由跳转进入之前,做一下判断,如果是从详细页跳转过来的就读取缓存的数据,如果不是就强制刷新页面。
在离开之前判断一下如果是调到详细页面就缓存,否则不缓存。
beforeRouteLeave(to,from,next){
if(to.name == 'detail'){ //如果是跳转进详细信息页面,则缓存当前页面
from.meta.keepAlive = true;
}else{ //跳转进其他页面则不缓存
from.meta.keepAlive = false;
}
next();
}
beforeRouteEnter(to,from,next){ if(from.name != 'detail'){//如果不是从详细页面跳转进来 var isRefresh = sessionStorage.getItem('isRefresh'); if(isRefresh == '0'){ //如果不是第一次进入该页面 sessionStorage.setItem('isRefresh',null); window.location.reload(); next(); }else{ sessionStorage.setItem('isRefresh','0'); next(); } }else{ next(); } }
这个页面的内容大概就是这样了。
之后就是最后一个页面,也就是详细页了。