pinia 的 timeline 很好很强大,只是到目前为止没有发现有定位的功能,就是说,如果状态发生异常变更的时候,如何快速找到,到底是哪一行代码触发的变更?
watch + error 定位代码
定位代码可以使用 Error 的方式来获得,那么这个Error放在哪里呢?
因为 pinia 的 store 本身就是一个 reactive,所以可以用 watch,不过不是在第二个参数,而是第三个参数的 onTrigger() 。
我们写一个函数(按照"流行"的说法,我们封装一个hooks。)
js
import { watch } from 'vue'
export default (store: any) => {
watch(store, (v) => {},
{
onTrigger(event) {
const err = new Error('记录调用函数')
console.log('err:', err)
console.log('onTrigger--event:', event)
},
})
}
函数需要传入一个 store,然后用 watch 进行监听,在 onTrigger 里面设置 Error(),用来记录调用的函数,然后打印出来就可以定位了,比如这样:
event 可以记录type、key、value等信息。
js
onTrigger--event: {type: "set", key: "name", newValue: "aa", ...}
这样哪个状态出问题就 watch 哪个,然后定位代码,就可以很快找到位置了。
适用范围
pinia 的状态有多种变更方式,每一种都可以吗?让我们挨个测试一遍:
方式 | 序号(从0开始) | 是否可行 |
---|---|---|
直接改属性 | 6 | 可以 |
action | 8 | 只能定位到定义的位置 |
$state | - | 好像差一行 |
$patch | 6 | 可以 |
$reset | 8 | 可以 |
在 template 里面也是一样的效果。
三种情况有效:直接改属性、 <math xmlns="http://www.w3.org/1998/Math/MathML"> p a t c h 、 patch、 </math>patch、reset()。
$state 内部调用 $patch,调用的太深,Error()只有十条记录,超出范围,暂时没有找到办法。
action 的定位方法
action 也比较深,如果想定位的话,可以使用 $onAction(),在里面设置 Error。
代码调整如下:
js
export default (store: any) => {
let isAction = false
watch(store, (v) => {},
{
onTrigger(event) {
if (!isAction) {
const err = new Error('记录调用函数')
console.log('err:', err)
console.log('onTrigger--event:', event)
}
},
})
store.$onAction((e: any) => {
console.log('action 的参数:', e.args)
const err = new Error('记录调用函数--onAction')
console.log('err:', err)
isAction = true
e.after(() => {
isAction = false
})
})
}
这样就可以了。
setup 的方式是否支持?
上面是 option 的方式,那么 setup 是否有效呢?还是老规矩,测试一下。
经过测试,结果也是一样的,都支持。只是 $reset() 不支持 setup 方式。
小结
优点:
- 侵入性小,不影响代码
- onTrigger 只在 开发模式有效,生产模式无效
缺点:
- 比较简单粗暴,没有优化。
- $state 没能实现定位。