记一个Vue项目的开发历程

来源:互联网 发布:js确认框 编辑:程序博客网 时间:2024/06/05 10:01

项目地址 https://github.com/hongchh/timeline-x

一、成品展示

1

2

3

4

二、项目需求

  • 添加每一天的时间记录,修改某天的时间记录(因为可能记错或者忘了记某项活动)
  • 每天的记录可以有多项活动,每项活动有对应的时间
  • 每项活动划分到特定的类型
2016-01-20,星期五1. 学习Vue, 5h,[学习]2. 跑步,0.5h,[运动]3. 看霹雳布袋戏,2h,[休闲]

2、数据分析

  • 按照月份统计每天的总时间,按照年份统计每月的总时间,按照分类统计各项内容的总时间
  • 以图表形式展示月份时间支出和年份时间支出的变化情况
  • 以图表形式展示各种类型的活动的时间支出情况
  • 计算总时间和平均时间

3、时光展示

  • 时光轴形式进行活动记录展示,便于回顾总结
  • 轮播图形式进行活动记录展示,便于回顾总结

4、数据模型

{  "items": [{    "content": "string",    "time": "number",    "type": "string"  }],  "year": "number",  "month": "number",  "date": "number",  "day": "number"}

数据示例

{  "items": [{    "content": "学习Vue",    "time": "5",    "type": "学习"  }, {    "content": "跑步",    "time": "0.5",    "type": "运动"  }, {    "content": "看霹雳布袋戏",    "time": "2",    "type": "休闲"  }],  "year": "2016",  "month": "01",  "date": "20",  "day": "5"}

三、开发思路

1、界面构成

  • 整个应用分成2个主要界面:【主界面】,【权限界面】
  • 【权限界面】用于用户登录,也是应用的启动界面
  • 【主界面】包含3个子界面:【管理】,【时光轴】,【时光展】
  • 【时光轴】和【时光展】用于时光展示
  • 【管理】用于展示数据分析结果以及编辑时光记录(添加/修改)

2、跳转关系

  • 【权限界面】验证成功之后跳转到【主界面】
  • 【主界面】默认展示【时光轴】界面
  • 【主界面】顶栏可以选择跳转到【管理】、【时光轴】或【时光展】界面
  • 【主界面】顶栏选择“锁屏”之后回到【权限界面】

3、组件划分

└─App:挂载整个应用   ├─Auth:【权限界面】   │  └─StarFlow:【权限界面】底部的动画   └─Main:【主界面】的基本结构      ├─Management:【管理】      │     ├─TimeAnalysisPerMonth:月份时间分析组件      │     ├─TimeAnalysisPerYear:年份时间分析组件      │     ├─TimeAnalysisByType:分类时间分析组件      │     └─EditTimeRecord:时间记录编辑组件      ├─Timeline:【时光轴】      └─TimeSlide:【时光展】

4、文件结构

└─build:构建用到的相关文件├─config:构建的配置文件├─server:应用的服务器源码│   ├─controller:服务端业务逻辑│   ├─model:数据存储逻辑│   ├─static:静态文件│   ├─views:应用的视图文件│   ├─app.js:express服务器配置文件│   └─server.js:服务器启动文件├─src:前端开发源码│   ├─assets:图片等静态资源│   ├─components:前端组件│   ├─router:前端路由│   ├─store:vuex的store│   ├─App.vue:应用的外层结构│   └─entry.js:应用的入口文件└─static:前端开发过程中用到的静态文件    └─data:存放伪数据以及伪数据生成器

四、开发历程

1、基础配置

使用vue-cli生成一个webpack项目模板

vue init webpack timeline-x

生成之后为了支持jade+sass开发,还需要安装相关的依赖

npm install node-sass --save-devnpm install sass-loader --save-devnpm install jade --save-dev

配置完成之后我们就可以在项目中使用jade和sass来进行开发了,.vue文件的模板如下,注意在template标签和style标签里面使用lang属性说明jade和sass。

<template lang="jade">div#auth  h1 Auth Page</template><script>export default {  name: 'auth'}</script><style lang="sass">#auth  border: 1px solid red</style> 

2、准备组件

按照之前划分好的组件,在src/components文件夹里面准备好相关文件。暂时不需要写入各组件的内容,就按照上面的模板一样写个标题说明这是哪个组件即可。

c

3、配置路由

组件都准备好之后安装路由

npm install vue-router --save

安装完成之后需要在使用路由的时候将其导入,我这里选择在router/index.js文件里面导入。

import Vue from 'vue'import Router from 'vue-router'Vue.use(Router)

按照前面确定好的页面跳转关系配置路由信息,然后测试界面跳转是否正常。

const router = new Router({  mode: 'history',  routes: [    { path: '/auth', component: Auth },    {      path: '/main',      component: Main,      children: [        { path: 'management', component: Management },        { path: 'timeline', component: Timeline },        { path: 'time-slide', component: TimeSlide },        { path: '', redirect: 'timeline' }      ]    },    { path: '/', redirect: '/auth' }  ]})

4、组件设计

UI方面使用了一些element-ui的组件,因此还需要先安装element-ui。同样地安装之后需要导入,导入方法类似之前的vue-router。注意这里还需要导入element-ui的样式文件index.css。

npm install element-ui --save
import Vue from 'vue'import ElementUI from 'element-ui'import 'element-ui/lib/theme-default/index.css'Vue.use(ElementUI)

3个时间分析图表使用的是echarts,需要先安装echarts。安装之后import需要用到的图表就行了,这样经过webpack构建之后的产品代码就只有用到的图表的那部分代码了,可以较少产品代码体积。

npm install echarts --save

由于我只用到了柱状图和圆饼图,然后图表上面还使用了标题和提示等组件,所以只需要在entry.js里面导入这些组件即可。

import 'echarts/lib/chart/pie'import 'echarts/lib/chart/bar'import 'echarts/lib/component/tooltip'import 'echarts/lib/component/title'import 'echarts/lib/component/legend'

到步骤【2】准备好的文件里面开始编写组件。在template标签中编写组件的HTML结构,然后在style标签中调节样式,业务逻辑则是放在script标签中。下面我用Auth.vue来作为例子,其他组件请参考github仓库里面的代码。

权限界面比较简单(参考上面的成品展示图),HTML结构如下,使用element-ui的栅格布局,同时用了另外一个动态背景组件star-flow。

div#auth  star-flow  div#auth-input    el-row(:gutter="20")      el-col(:span="8", :offset="8")        el-tooltip(:disabled="disabled", :content="errorTip", placement="bottom-start", effect="light")          el-input(placeholder="请输入密码", v-model="password", type="password")            template(slot="append")              el-button(@click="signin") Go

样式如下,设置一下背景图、宽高度之类的。

#auth  width: 100%  height: 100%  background: url(../../assets/auth-bg.jpg) no-repeat  background-size: 100% 100%  background-attachment: fixed  #auth-input    position: absolute    width: 100%    height: 10%    top: 45%

下面是js部分了,使用es6的写法,为了使用另一个组件,需要先将其import进来然后添加到components里面。export是将当前的组件导出,其他模块才能使用到。data里面写该组件用到的数据项,methods则是这个组件里面需要的方法函数了。(有点类似angular的controller)

import StarFlow from './StarFlow'export default {  name: 'auth',  components: { StarFlow },  data () {    return {      password: '',      disabled: true,      errorTip: ''    }  },  methods: {    setTip (tip) { // 消息提示,1.5秒后自动关闭      this.errorTip = tip      this.disabled = false      setTimeout(() => {        this.disabled = true        this.errorTip = ''      }, 1500)    },    signin () { // 验证密码解除锁屏      if (!this.password) {        this.setTip('密码不能为空')      } else {        this.$store.dispatch('unlockScreen', this.password)        .then((err) => {          if (err) this.setTip('密码错误')          else this.$router.replace('/main')        })      }    }  }}

5、改善UI

调整组件的样式,并且改进应用的样式,添加过渡动画。过渡动画直接在router-view外面套一个transition,然后编写相应的过渡样式即可,很简便。

6、数据状态管理

该项目由6个组件需要用到同一份数据,1个记录编辑组件、2个时光展示组件和3个数据分析组件。为了方便数据管理,同时也好制造机会学习Vuex,因此我这里引入vuex来进行应用的状态管理。安装vuex,然后在store/index.js里面导入vuex。

npm install vuex --save
import Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)

定义1个store存放应用的全局状态:锁屏变量和时间记录。默认开启锁屏,所以lockScreen设置为true,而timeRecords则是一个时间记录数据,里面包含多条记录。这些数据在应用启动接触锁屏之后向服务器获取,在还没有开发服务器的时候,为了完成前端开发可以先在这里写一些伪数据进去。

const store = new Vuex.Store({  state: {    lockScreen: true,    timeRecords: []  },  mutations,  actions})

在store/actions.js和store/mutations.js里面定义这些全级状态可能发生的变化。如果涉及到异步操作,则将这些涉及异步的变化放到actions.js里面,例如向服务器获取数据这个操作就是一个异步的,应该将其代码放在action里面。根据Vuex文档的介绍,mutation的代码必须要是同步的。

由于涉及跟服务器的交互,所以我们还需要一个提供http服务模块。上网查了查,有vue-resource这个东西可以用,不过好像更推荐使用axios,因此我这里也选择使用axios。下面进行安装和导入。

npm install axios --save
import axios from 'axios'

准备好了之后可以开始编写了,下面是actions.js的代码,其他代码请参考github仓库。实现了后台交互功能,然后通过commit相应的mutation来更新store里面的状态。注释部分的代码是在前端开发还没有服务器的时候使用的开发代码。

export default {  unlockScreen ({commit}, password) { // 验证密码,接触锁屏    // 使用"npm run dev"启动时候请解除下面代码的注释,注释后面的POST代码    // return new Promise((resolve, reject) => {    //   commit('UNLOCK')    //   resolve(false)    // })    return axios.post('/api/check', {      password: password    }).then((res) => {      if (!res || res.status !== 200 || res.data.err) {        return true      } else {        commit('UNLOCK')        return false      }    })  },  addRecord ({commit}, record) { // 添加记录    // 使用"npm run dev"启动时候请解除下面代码的注释,注释后面的POST代码    // return new Promise((resolve, reject) => {    //   commit('UPDATE_RECORD', record)    //   resolve(false)    // })    return axios.post('/api/add', record).then((res) => {      if (!res || res.status !== 200 || res.data.err) {        return true      } else {        commit('UPDATE_RECORD', record)        return false      }    })  },  fatchData ({commit}) { // 获取数据    axios.get('/static/data/data.json').then((res) => {      if (res.status === 200) {        commit('FATCH_DATA', res.data)      }    })  }}

7、准备伪数据

为了让应用有更多数据可以呈现,需要自行编造一些伪数据,我写了一个伪数据生成器,即static/data/data-generator.js。运行之后产生100多条时间记录并存放到json文件里面。具体请参考github仓库。

8、完善锁屏

实现锁屏功能其实不难,只要在权限界面检验之后更新store里面的锁屏状态为false,在主界面点击顶栏的锁屏之后更新store里面的锁屏状态为true即可。但为了更完善,还需要在路由里面设置一个全局钩子,在进入相应界面之前检查一下store的锁屏状态,例如,在访问主界面的时候需要检查store里面的锁屏状态是否为true,如果是的话强行给它重定向到权限界面,因为这可能是用户通过手动修改URL来访问的。

这里有一个坑,在router的全局钩子里面访问不到store里面的状态。在stack-overflow里面找到了这个解决方案,把store也给import到router里面去,这样就可以访问到了。不知道有没有其他更优秀的方案,欢迎交流。

import store from '../store'router.beforeEach((to, from, next) => { // 对特定路径进行验证,增强锁屏功能  if (to.path === '/') {    next('/auth')  } else if (to.path === '/auth' && !store.state.lockScreen) {    next('/main')  } else if (to.path !== '/auth' && store.state.lockScreen) {    next('/auth')  } else {    next()  }})

9、后台开发

前端开发基本完成之后就可以开始后台开发了,我后端使用的是express框架,按照MVC模式进行开发。由于本项目关注的是前端开发,所以后端就写得比较简单,也没有用上数据库,没有什么好讲的。主要有一点需要注意,为了方便,我更改了build的目标路径。用vue-cli生成的webpack项目build之后是在主目录下面生成一个dist文件夹来存放产品文件,我将其改成build之后静态文件放到server里面的static文件夹,而index.html则放到server里面的views文件夹,这样就不用手动去搬dist里面的文件给服务器用了。改动很简单,只需要该config/index.js里面的7-8行即可。

index: path.resolve(__dirname, '../server/views/index.html'),assetsRoot: path.resolve(__dirname, '../server'),

10、前后对接

对接前端和后台的接口,调整代码,修正bug。如果一开始将接口想清楚、设计好的话这里基本没有什么难。本项目只有2个post数据和1个get数据的接口,没有难度。

11、改进,修正小问题

五、结束

大概用了5天写这个项目,基本入门了Vue,还是一次蛮不错的体验。为了多点练习强行加入了vuex,虽然官方推荐不要在小项目里面使用vuex,但我觉得引入vuex之后还是可以解决很多问题,思路也清晰了很多。在用vuex之前的想法是在一个外层的组件里面获取数据然后传递给子组件。后来发现如果我在编辑记录组件里面更新或者添加了一条记录,父组件和其他兄弟组件的数据不会收到更新。如果通过$emit来让父亲组件更新数据然后再使得兄弟组件更新,整个过程又太过繁琐。而Vuex的思路是弄一个全局状态来对数据进行管理,组件树上的组件都可以更新状态,状态变化之后会反馈到相应的其他组件上。这个思路很清晰,代码写起来也很顺利,也体验了vuex的强大,确实可以省事很多。

部分内容可能无法讲得很清楚,有兴趣了解的话请参考github仓库的代码和commit记录。下面说说几点收获:

  • es6写起来感觉超棒
  • webpack比gulp优雅
  • vue值得尝试
0 0
原创粉丝点击