OKR(Objectives and Key Results)即目标与关键成果法,可以理解为对目标完成情况的一种管理方法。
一般需要列出当前周期的目标,然后列举一些关键结果来衡量目标的完成情况。

我个人的情况是,以每两个月为一个周期设定自己的目标。最初都是用markdown记录,每次列出表格,写下目标,结果,进度,最后给自己算分数。
手工记录
然而这个算分的过程每次都得重新计算,十分麻烦,而且表格也得手工维护,总之就是麻烦。于是就有了写个软件管理的想法。
正好自己主要是做后端,所以想学习下前端知识,于是把这款软件定位在web应用上。

1. 产品设计

先给自己写了个简单的PRD(产品需求文档),大概自己能看懂就ok,理了理思路。传送门

2. 环境配置

  1. 安装npm,获取npm
  2. 安装vue,官方安装方法
  3. IDEA作为IDE

3. 新建项目

使用命令vue ui开启图形界面,新建项目,有个默认初始化git选项,按照喜好可要可不要
初始化

“预设”选项,选择“手动”,然后勾上这些包vuexrouter,不选包linter
选择包

之后勾选使用html5历史模式
勾选历史模式

进入项目web管理页面后,添加element-ui模块
安装插件

项目建立后导入到IDEA,就可以开始编写代码了。

4. 难点记录

这一部分只挑一些重点来说,剩余的可以参考git仓库代码:ot

主要用了两个页面,App.vue作为整个门面,保持不变,主要用于展示OKR的可选月份,图中红色圈出的部分即是。Home.vue承接OKR的展示部分,为图中的非红色部分。
结构

月份展示

提前算好月份列表,默认显示当前双月的目标。这里用v-model指定默认打开的tab。详细参考:官方文档-tabs
注意<router-view>别放在循环里面,这样会产生多个,实际上我们只需要一个。

c1

数据传递

当点击月份标签的时候,使用$router.push把月份信息传递到Home.vue。这里有个点要注意,push方法在推送的URL和当前URL相同时,会在控制台报错。这里加了个catch忽略掉报错。

this.$router.push({path: '/okr/', query: {'month': tab.label}}).catch(() => {});

由于使用的是同一个Home.vue,所以靠query词来区分页面。改写router/index.js来映射到Home.vue

const routes = [
  {
    path: '/okr/*',
    name: 'home',
    component: Home
  }
];

Home.vue考虑

本来只用了<el-table>,后来发现需要标题,所以在外面嵌套了<el-card>,最终布局是:
c2

固定最后一行百分比

为了保证最后百分比总和为100%,就打算固定最后一行为不可更改的形式。
这里用了一个字典存是否可以修改hitBox: {},key是目标+结果+列名,可以唯一确定一个单元格。
c3

v-slot用于获取父组件的数据,使其可以传递下来,具体参考:编译作用域

数据刷新

有两种情况页面需要刷新。一个是当双击单元格时,此时要显示单元格成编辑框,所以必须刷新页面。另一个是数据变动时,此时需要刷新页面。所以要特别注意hitBox,在第一种情况下,不需要刷新,否则单元格又变回原样。

// 同样的页面,不需要初始化的数据
if (!isOldPage) {
    this.hitBox = {};
    this.editData = false;
}

数据直接用localstorage存,使用方式就是k-v,将结构化数据序列化后使用即可。

let tableData = localStorage.getItem(this.month);
tableData = JSON.parse(tableData);

5. 部署到github pages

官方说的很明白:传送门

部署完之后就可以愉快地使用啦~

6. 效果

项目github地址:https://github.com/GooZy/ot

部署页面:https://goozy.github.io/ot/

参考资料

  1. 【2020版】4小时学会Spring Boot+Vue前后端分离开发
  2. VUE+Element UI实现简单的表格行内编辑效果
  3. Vue结合Element-UI实现单元格编辑、删除等操作