1. 做一个新闻展示页
2. 新闻分类可以自定义
3. 每类新闻的内容,样式不一样
4. 上拉加载新的数据
5. 点击进入详情页,再返回时,定位到原来的位置
图片展示
轮播图使用:swiper
zepto.js
vue.js
vue.resource.js
vue-router.js
滑动插件:iscroll.js
界面样式采用的 weui
因为使用了vue.js 每个分类的样式不一样,而且分类是可以配置的。所以呢,想到了单页面应用,所以选择了vue-router.js的路由。也使用了vue.resource 插件用来做数据传输。
因为我比较菜,所以呢还是使用的原始的引入方式,没有使用webpack之类的打包工具,就最原始的js 写法。
使用了路由,是为了返回的时候,可以回到刚才离开的地方,vue虽然有自带的keep-alive 但是似乎必须使用路由的history模式,还要修改服务器端的东西,所以感觉不是很合适。而且我们需要Ajax加载数据,怎样能返回路由的时候,展示ajax加载的内容呢?
我想到了记录个数,每次进入路由再从这个数开始加载,但是呢我们没有下拉更新,用户再也看不到之前看的内容。
后来我想到了H5 的缓存方法。使用了sessionStorage。
sessionStorage用于本地存储一个会话(session)中的数据,这些数据只有在同一个会话中的页面才能访问并且当会话结束后数据也随之销毁。因此sessionStorage不是一种持久化的本地存储,仅仅是会话级别的存储。
再离开一个路由之前,把这个路由现在状态信息全部记录下来(包括提示语,滑动位置,新闻内容等),等下次进入这个路由的时候,再取出来数据这样就实现了不管加载多少数据,再次进入这个路由的时候,都可以和上一个衔接上。
有一个重要的地方是:sessionStorage 是有最大容量的,应该是有容量限制的,我找了找localStorage 5M左右,sessionStorage 我还没有找到,但在项目中运行情况来看,暂时稳定。
路由的定义
重点的是每个组件里面的方法
每个组件都共用的data
, create
和 methods_all
var returndata={
swipertime:swipertime,
demoData: [],
demoData2:[],
message:'正在加载数据',
iscrollaction:false,
token:'{pigcms:$token}',
cdn:"{pigcms::C('cdn_images')}",
param:{
api_url:"{pigcms::C('api_weixin')}",
local_url:"{pigcms::C('site_url')}",
classid: -1,
startnum: 0 ,
other:''
},
ajax_status:false,
huadong:true,
}
//组件开始的时候,先注销掉上一个组件的滑动,然后查看缓存里面有没有数据,如果有缓存就进入缓存里面,如果没有,就重新加载
var create=function() {
var that = this;
if (that.myScroll){
that.myScroll.destroy(); //把滑动注销掉
}
var session_name=this.$route.path;
if(sessionStorage[session_name]){ //说明缓存里面有
that.session_data();
}else{
that.ajax_data();
}
};
//有缓存的处理办法
session_data:function () {
var that = this;
var session_name=this.$route.path;
//把缓存内容取出来
var session_data= JSON.parse(sessionStorage[session_name]);
for (x in session_data){
switch(x){
case 'data1':
that.demoData=session_data[x];
break;
case 'data2':
that.demoData2=session_data[x];
break;
case 'scroll_y':
var scroll_y=session_data[x];
break;
case 'iscrollaction':
that.iscrollaction=session_data[x];
break;
case 'startnum':
that.param.startnum=session_data[x];
break;
case 'other':
that.param.other=session_data[x];
break;
case 'message':
that.message=session_data[x];
break;
case 'classid':
that.param.classid=session_data[x];
break;
}
}
Vue.nextTick(function () {
//初始化滚动插件
that.myScroll = new IScroll('#wrapper', {
mouseWheel: true,
wheelAction: 'zoom',
click: true,
scrollX: false,
scrollY: true,
startY:scroll_y,//滑动定位到原来的位置
});
//滚动监听
that.myScroll.on('scrollStart',that.showbox);//滚动监听,1000
that.myScroll.on('scrollEnd',that.scrollaction);//滚动监听,1000
that.myScroll.refresh();
})
},
//没有缓存重新加载
ajax_data:function(){
var that = this;
if (this.$route.params.id != ''){
that.param.classid=this.$route.params.id;
}else{
that.param.classid=-1;
}
that.param.startnum=0;//初始化数据
var url = that.param.api_url + ******' + that.token + '&classid=' + that.param.classid + '&offset=' + that.param.startnum;//接口url
that.$http.jsonp(url).then(function (response) {
var res = response.data; //取出的数据
this._data.demoData2 = res.new;
this._data.demoData = res.data;
this._data.param.other = res.other ;
var listdata = res.data; //数据
var code = res.code; //状态值
if (res.other !== 1) {
if (code == '20001') {
if(listdata.length == 10){
that.iscrollaction = true;
that.message='正在加载数据';
}else{
that.iscrollaction = false;
that.message='没有更多资讯';
}
}else if (code == '20002') {
that.iscrollaction=false;
that.message='没有更多资讯';
} else if (code == '40001' || code == '40002') {
that.message='访问错误';
that.iscrollaction=false;
}else{
that.message='暂无数据';
that.iscrollaction=false;
}
} else {
that.iscrollaction=false;
}
that.param.startnum = listdata.length;
Vue.nextTick(function () {
//初始化滚动插件
that.myScroll = new IScroll('#wrapper', {
mouseWheel: true,
wheelAction: 'zoom',
click: true,
scrollX: false,
scrollY: true,
});
//滚动监听
that.myScroll.on('scrollStart',that.showbox);//滚动监听,1000
that.myScroll.on('scrollEnd',that.scrollaction);//滚动监听,1000
//把数据放在缓存里面
var session_name=that.$route.path;
var session_all={};
session_all.name=session_name;
session_all.data1=that._data.demoData;
session_all.data2=that._data.demoData2;
session_all.scroll_y = 0;
session_all.iscrollaction=that.iscrollaction;
session_all.startnum= that.param.startnum;
session_all.other= that.param.other;
session_all.message= that.message;
session_all.classid= that.param.classid;
var session_all = JSON.stringify(session_all);
sessionStorage[session_name]=session_all;
})
}, function (response) {
//取消加载效果
loadingToast.css('display', 'none');
that.message='服务器维护,请稍后重试';
});
},
最折磨我的还是iscroll的问题,我们用的vue,所以呢 我的点击都是用v-on:click
这种方式来完成的,但是呢,刚开始用iscroll的时候,点击不生效,后来是给 iscroll的options.click
设置为true
才可以点击。
后来有一个难题是:在滑动过程中点击会出发跳转,(本意是滑动一下会再次点击希望他停止滑动,却发生了跳转),造成了不好的体验。我去看了其他的网站, 有的安卓会发生,苹果不会,有的是苹果发生,安卓不会。让我不知道应该怎么办。
sessionStorage 和 localStorage的区别
而localStorage用于持久化的本地存储,除非主动删除数据,否则数据是永远不会过期的。
这是我现在的处理方案,如果哪位大神觉得这么做不妥,有更好的方法可以告诉我.