Hexon(曾用名winwin-hexo-editor)是我开发的用于在线编辑 hexo 文章的编辑器。本文记录了我在开发中学到的部分知识。

OAuth token 的逻辑

分为access tokenrefresh token。仅在授权服务器和资源服务器的安全等级有较大差异的时候分为两个 token 才有安全作用。此外,分开 token 可以减轻服务器的查询负担。

没有 refresh token:

  • 发送带有 access token 的请求
  • 服务器检索 access token 表,确认 token 是否过期或被撤回
  • 如果是,返回失败,要求用户重新登录

有 refresh token

  • 发送带有 access token 的请求
  • 如果 access token 过期,使用 refresh token 申请新的 access token
  • 服务器接受刷新申请,检索 refreshtoken 表,确认 token 是否过期或被撤回
  • 如果是,返回失败,要求用户重新登录
  • 否则返回新的 access token,用户重新尝试申请

使用 refresh token 后的表检索次数由请求频率x用户数,降低到了请求频率/access token有效期内的请求数量x用户数。有利于代码的规模化。

如何实现 vue 的连续载入中界面

  1. 在 app 加载之前:使用原生 html 写加载界面
  2. 在 app 加载之后,用 vue 写加载界面,删除原生加载
  3. 在 router 时候,更新加载界面内容。使用 vuex
  4. 在加载组件的时候,更新加载界面内容。使用 vuex
  5. 组件加载完成后,关闭加载界面。还是使用 vuex

需要注意

如果有异步操作,需要确保所有操作完成后再关闭加载界面。具体实现,计划使用一个 map 来记录不同加载开始的申请是否结束。例如,component#1 申请了加载界面,那必须在加载结束时申请关闭。

如果每个操作结束都关闭,那可能会造成界面闪烁。

Vue 和 Router 初始化的时候都干了什么

  1. 加载应用 // 此时 vue app 不可用
  2. 渲染应用 // 渲染完成后 app 可用,渲染时间可以忽略不计
  3. 如果有路由
    1. 依次运行路由钩子 // 可能涉及到钩子中的网络请求造成的延迟
    2. 加载路由对应组件 // 加载组件需要时间
    3. 渲染路由对应组件 // 渲染时间可以忽略不计

vue 在路由切换后,新组建载入前,如何加入动画

()=> import('xxx.vue')只是一个普通的函数,可以对这个函数做手脚。在函数运行前后添加状态指示。

注意:由于 webpack 的机制,这个函数必须整体作为参数!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import { Logger } from "src/utils/logger";
import Vue from "vue";
const logger = new Logger({ prefix: "async load" });
const state = {};

/**
* 懒加载模块,记录加载状态
* @param {Function} fn `()=>import('xxx)`
* @param {String} name 随便指定一个名称,需要唯一
* @param {Object} meta 附加数据,仅用于描述,不影响懒加载
* @param {Number} delay 延时
*/
function load(fn, name, meta = {}, delay = 200) {
if (!name) throw new Error("name is required");
if (Object.keys(state).includes(name))
throw new Error("duplicate async load name:", name);
logger.log("registed:", name);
Vue.set(state, name, {
loading: false,
error: false,
meta,
});
return () => {
const token = window.setTimeout(() => {
state[name].loading = true;
logger.log("start loading:", name);
}, delay);
const done = (v) => {
if (token) window.clearTimeout(token);
state[name].loading = false;
logger.log("end loading:", name);
return v;
};
return fn()
.then(done, done)
.catch((e) => {
state[name].error = true;
logger.log("fail loading:", name);
return e;
});
};
}

export default {
state,
load,
};

什么时候判断是否要弹窗

在调用 Action 的时候(也就是类似在用户点击某个按钮的时候),去判定需不需要弹窗询问用户意见,然后再根据询问结果进行下一步操作。Action 不进行和 ui 有关的操作,只更新数据。

故事点

到底什么是故事点(Story Point)?

故事点是一个度量单位,用于表示完成一个产品待办项或者其他任何某项工作所需的所有工作量的估算结果。

按照这个列表里面的情况(指 TeamBition 中的故事点选项),随便搞搞 0.5,半天是 1,一天是 2,两天是 3,三天是 5,4 天是 8,5 天是 13
sp 不一定是真实的,只是一个预估值,来表明你对这个 ticket 做起来,觉得复杂程度的预估

什么时候需要路由?

用户刷新后需要回到当前页面的时候

在何处存储组件依赖的数据、

  • 组件内部:数据只在组件生命周期内使用
  • 某一个父组件内部:数据有多个子组件在使用
  • 单独存储:数据在应用打开周期内都可用
  • 持久化存储:数据一直可用