OKR(Objectives and Key Results)即目標與關鍵成果法,可以理解爲對目標完成情況的一種管理方法。
一般需要列出當前週期的目標,然後列舉一些關鍵結果來衡量目標的完成情況。
我個人的情況是,以每兩個月爲一個週期設定自己的目標。最初都是用markdown記錄,每次列出表格,寫下目標,結果,進度,最後給自己算分數。
然而這個算分的過程每次都得重新計算,十分麻煩,而且表格也得手工維護,總之就是麻煩。於是就有了寫個軟件管理的想法。
正好自己主要是做後端,所以想學習下前端知識,於是把這款軟件定位在web應用上。
1. 產品設計
先給自己寫了個簡單的PRD(產品需求文檔),大概自己能看懂就ok,理了理思路。傳送門
2. 環境配置
3. 新建項目
使用命令vue ui
開啓圖形界面,新建項目,有個默認初始化git選項,按照喜好可要可不要
“預設”選項,選擇“手動”,然後勾上這些包vuex
和router
,不選包linter
之後勾選使用html5歷史模式
進入項目web管理頁面後,添加element-ui
模塊
項目建立後導入到IDEA,就可以開始編寫代碼了。
4. 難點記錄
這一部分只挑一些重點來說,剩餘的可以參考git倉庫代碼:ot
主要用了兩個頁面,App.vue
作爲整個門面,保持不變,主要用於展示OKR的可選月份,圖中紅色圈出的部分即是。Home.vue
承接OKR的展示部分,爲圖中的非紅色部分。
月份展示
提前算好月份列表,默認顯示當前雙月的目標。這裏用v-model指定默認打開的tab。詳細參考:官方文檔-tabs
注意<router-view>
別放在循環裏面,這樣會產生多個,實際上我們只需要一個。
<el-tabs tab-position="left" style="height: 100%;" v-model="activeTab" @tab-click="handleClick">
<el-tab-pane v-for="(month, index) in monthList" :label="month" :name="index+''" :id="index=''">
{{month}} ORK情況一覽
</el-tab-pane>
<router-view></router-view>
</el-tabs>
數據傳遞
當點擊月份標籤的時候,使用$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>
,最終佈局是:
<el-card>
<el-table></<el-table>
</el-card>
固定最後一行百分比
爲了保證最後百分比總和爲100%,就打算固定最後一行爲不可更改的形式。
這裏用了一個字典存是否可以修改hitBox: {}
,key是目標+結果+列名
,可以唯一確定一個單元格。
<el-table-column label="關鍵結果" min-width="35">
<template v-slot="scope">
<span v-if="hitBox[scope.row.object+scope.row.key+scope.column.label]">
<el-input type="textarea" size="small" v-model="scope.row.key"></el-input>
</span>
<span v-else>{{scope.row.key}}</span>
</template>
</el-table-column>
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/