vue初体验

最近QA提了一个问题,我原来做的到账记录的页面从列表页点进详情页之后返回列表页的时候不能返回到之前进去的位置。当时写这个页面的时候也遇到了一些问题,具体可以看这里到账记录的页面

因为当时做到账记录这个页面时是两个页面,列表页是通过接口的数据生成的,页面并不会缓存,进入详情页返回列表页时数据要重新请求,所以不能回到当时的位置。正好最近公司准备开始使用vue,所以我就用vue重构了这个页面,vue自带路由,因为是单页面所以列表页也可以保存起来。

用了一次vue就会觉得他很方便,用vue就不需要再使用模板来渲染页面了,他自带过滤器功能在渲染模板的时候就可以过滤字符串,自带路由功能。

先给出两个文档的地址,一个是vue的文档,另一个是vue的官方路由组件的文档。这里写的非常的详细,在这里可以找到所有的答案。

说说过程中的经验。

vue在编写组件的时候,也支持使用模板。

在html中可以像用模板语言那样,写一个script标签,定义一个id,在这个标签内写相应的组件的html。

1
2
3
<script id="list-template" type="text/x-template">
.....
</script>

然后在js的组件内引用这个模板就可以了。

1
2
3
var List = Vue.extend({
template: '#list-template'
})

传递参数

整个到账做成了一个页面,就会包含列表和详情两个组件。原来是两个页面的时候是使用url来传递参数(比如详情页要使用列表页的单号来请求后台接口),现在传递参数会有两种方法:

  1. 因为路由需要一个根组件,可以在根组件上定义一个变量,点击列表组件的时候把单号传到根组件的变量中,在详情组件中取根组件的这个变量,得到单号。
  2. 就是用sessionStorage,在点击列表时绑定一个事件,把单号存到sessionStorage中。

我是选择用第二种办法,因为他过程更方便,容易理解。在组件中都会有生命周期(可以看路由组件的文档),在组件创建的时候就从sessionStorage中取单号就可以了。

需求中的列表返回到进入时的位置其实也是用sessionStorage实现的。

下拉加载

使用的下拉加载和原来的页面没有区别,都是给window绑定一个监听事件,监听滚动条的高度判断是否到页面的底部,然后去加载列表。

但是在单页面中,需要注意如果监听事件一直存在的话,进入详情页后下拉到底部还是会加载列表,所以在列表页的deactivate的生命周期中需要把监听事件去掉,在activate的时候再继续去监听。

页面加载慢

在进入详情页后,如果后台返回数据过多,页面渲染会很受影响,在性能比较差的手机上可能会导致卡死或者app崩溃。这是因为后台一次性返回的数据太多,当反应这个问题后,后台由于其他业务的关系不能添加分页的功能,但是由前端自己也可以实现分布加载数据的功能(当然这是在万不得已的情况下,其实最好还是做分页)。

首先后台返回了一个很长的数组,我们需要的是把他缓存起来,首次渲染时只渲染一部分,在页面到达底部的时候再去加载。因为是单页面,不存在刷新的问题,所以把数据缓存在js的一个变量当中就可以了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*
*detaillist: [], //整个列表缓存
*load_list : [], //初次加载的列表
*page_count: 30, // 分页大小
*this_page: 0, // 当前页
*/

pushData: function() {
var _this = this;
var len = _this.detaillist.length;
for(var i = 0; i < _this.page_count && (_this.load_list.length < len) ; i++){
_this.load_list.push(_this.detaillist[_this.page_count * _this.this_page + i]);
};
_this.this_page++
}

这个是详情页到底部时所执行的方法。有一点需要注意,就是在详情组件每次activate的生命周期的时候,需要把数据都重置,因为如果没有重置数据的话,变量里保存的还是原来的数组,渲染页面时数据就不对了。重置可以先一个函数来实现。

1
2
3
4
5
6
7
8
9
init : function(){
this.$set('monthfee', '');
this.$set('totalfee', 0);
this.$set('totalmoney', '');
this.$set('feedetail', '');
this.$set('load_list', []);
this.$set('this_page', 0);
this.$set('detaillist', []);
}

*这种方法有弊端,就是如果详情的数据特别特别多,这个页面就会越来越大,越来越卡,有另一种可以动态加载无限列表的库,iscroll-infinite.js,他可以不断的操作DOM来添加和删除列表。