为了以后的面试不至于忘记,觉得有必要做下总结,不然以后忘了很多项目的细节。
项目介绍
一个面向内部的项目,在项目中我和另一个实习生负责做数据统计功能,主要是关于PV、UV、播放量、下载量、使用时长等数据的统计,我主要负责的是前端部分。
项目使用的技术框架主要是express+ejs+vue,使用echarts来做可视化,用了iview组件库,还包括一些moment.js、mysql.js、axios.js等函数库的使用。用webpack做构建打包,用git做版本管理,此外还学到了js设计模式的应用、如何调试以及部署应用,整个开发过程周期非常完善,也在一些难点中得到了锻炼。
前端状态管理部分介绍
说下前端部分,我们没有使用vux来做状态管理,而是基于flux架构思想实现了自己的状态管理。总的来说就是:
把状态放到data.js的store里,把更新状态的方法也放到data.js里,再把data.js的store赋值给vue根实例的data,然后再通过props将根实例的data分发给不同的子组件。
要触发状态更新的话,就在子组件中引入store的data.js文件,再调用获取后台数据更新状态的方法。
和vue官网中的简单的状态管理有点类似:https://cn.vuejs.org/v2/guide/state-management.html
示例模板如下:
index.js
import Vue from 'vue' import dataApp from 'dataApp.vue' import data from "data.js"; new Vue({ el: '#app', data: data.store, render: h => h(dataApp) })
data.js
export default { store: { dataA:..., dataB:..., //各种状态数据 }, //更新状态的方法 a(){}, b(){}, ... }
dataApp.vue
<template> <componentA :dataA="this.$root.$data.dataA"></componentA> <componentB :dataB="this.$root.$data.dataB"></componentB> </template>
触发状态更新就是import data.js后再去调用其中的方法,略。
我学到了什么?
- webpack、babel等相关知识
- git相关命令知识
- express框架的理解与使用
- vue框架的理解与使用
- echarts、iview等组件库的使用
- moment.js、mysql.js、axios.js等函数库的使用
- sql命令的复习与使用。
- JS设计模式的运用
- 设计、调试、分析、检索信息能力的增长
项目难点
1.如何统计PV、UV、平均停留时长
停留时长计算规则:
每次进入页面的时候记录下访问时间starttime以及referer url,然后从localStorage中拿出上个页面的访问时间starttime,
用start_time-start_time得到的结果就是上个页面(refered url页面)的停留时长staytime。 然后在这个页面把上个页面的username、starttime、pageurl(也就是刚刚记录的referer url)等字段作为一条PV数据发给发给后台
拿PV数据时sql语句就在时间段内count(),要拿UV数据就distinct username,要拿平均停留时长就累加时间段内的staytime值。然后后续格式方面操作交给前端处理。
2.日期选择组件的改造。
因为产品要求日期组件datapicker能实现选择自然日、自然月、自然周的功能,于是我尝试了几个关于vue的ui组件库,主要是elment-ui和iview这两个 发现都不能满足,就选了最接近的iview,对于iview-datepicker的改造主要在于熟悉这个组件的官方文档,以及通过查看dev-tool,并使用jquery来完成组件事件与样式的定制。
不过还是不能满足产品的需求,而产品之所以有这样的需求是因为内部的平台用过这样的日期组件,后来在产品的帮助下找到了这个日期组件轮子的创造者。我研究了日期组件轮子的代码,轮子写的很好,
我只需要根据我的需要定制我的功能,完成项目后研究了下这个轮子是怎么写的,希望以后也能写出这样优秀的轮子。
3.echarts的状态响应与vue的状态响应的相冲突。
由于接口的问题,导致我需要在一个方法中去调用四次同一个方法去获取数据,也就是发送了4次请求,所以显示的数据顺序是获得数据先后的顺序,然后产品要求饼图展示的数据需要按顺序。
我试过用排序以及用赋值而不是push去卸载数据,也使用过promise,都无法处理顺序不一致的问题。于是要求后台把4个接口统一到1个接口,这样就不存在异步调取的先后问题。
此外卸载数据时使用了一个临时dataTmp对象去卸载数据下来,再用push(...data)方式装到store中的data里,这样也避免了echarts和vue状态响应相关的坑。
4.对echarts中图表的一些定制。
比如echarts中的饼图的图例只能展示名字,而需求是希望能够展示数据,所幸查了官方文档发现formatter的值可以是函数,于是使用了函数对图例格式改造了下,使得其能展示更丰富的数据。
还有做柱状图时,需要对同一类型的柱子进行颜色的改造,也是利用了color的值可以是函数,所以感觉echarts很强大,自己能够根据需要定制,当然阿里的AntV也很强大。
5.对打包的js文件的优化。
在没有做任何优化前,虽然已经分离公共的js文件,比如momet.js和axio.js单独打包成js文件,打包后的dataStatistics.js文件居然还有20M。
后面就找到原因优化了下,主要是对使用的echarts.js进行构建出包含所需功能的echarts.min.js。同时按需引入iview组件。当然分离js文件,将公共部分的js文件,
比如momet.js和vue.js和axio.js单独打包成js文件。这样做后dataStatistics.js文件缩小到了7.5M,经过gzip压缩后发到前端的只有1.5M。
可是还是很大,于是我就找原因,通过注释import语句后再打包文件看大小来判断是哪条import语句出了问题。
发现是引入iview的时候,虽然我按照官网文档使用babel-plugin-import插件去做按需引入,但是实际效果并没有做到按需引入。我猜测可能是版本的问题,后面我查了下,
配置babel-plugin-import有两种方式,可以在babelrc里面,也可以在webpack里面,但是当前版本下在babelrc里面配置就会出现不生效的问题。
不过我当时是改写了import语句,直接引入iview目录下的对应组件。比如import Progress from 'iview/src/components/progress'。
重新打包后的js文件只有3.8M,经过gzip压缩后发到前端的只有900多K,大小减少了很多。