需求背景: 项目重构差不多了, 需要在部分路由中加个登录埋点。但问题来了, 因为这个登录是写在router.beforeEach 中的,埋点需要页面中的配置数据。 思来想去试了好几种方法没有完美解决, 各位看官有更好的方法,多多交流
思路一
是在路由beforeEach 钩子中在 即将跳转的时候通知我可以访问到页面了
- 用了eventBus 来发送通知
router.beforeEach(async (to, from) => {
try {
const phone = await getAppUserInfo(to)
await userStore.phoneLogin(params)
emitter.emit('triggerAutoLogin','success') // 抛出登录成功事件
return true
})
}catch (error) {}
// 页面中监听
<script lang="ts" setup>
emitter.on('triggerAutoLogin',()={
})
</script>
结果: 初始化不会执行, 路由变化的时候回执行。 感觉像是第一次没注册进来的样子~~
- nextTick 和 setTimeout
router.beforeEach(async (to, from) => {
try {
const phone = await getAppUserInfo(to)
await userStore.phoneLogin(params)
setTimeout(() => {
emitter.emit('triggerAutoLogin','success') // 抛出登录成功事件
}, 0);
return true
})
}catch (error) {}
// 页面中监听
<script lang="ts" setup>
emitter.on('triggerAutoLogin',()={
})
</script>
结果: 初始化不会执行, 路由变化的时候回执行。如果定时器的延迟时间不能确定, 放到下一个事件循环里也没用~
- router 打标记,埋点成功后删除
我想了这种方式, 记在window也行, 虽然能解决 但没用
思路二
我又想了下, 不就是获取每个页面中的配置数据吗, 配置文件是单独的, 只要根据url动态获取数据不久行了, 如果以后要获取组件数据的话也可以改造。 于是就想到了import
ES2020提案 引入import()
函数,支持动态加载模块
import()返回一个 Promise 对象。下面是一个例子。
const main = document.querySelector('main');
import(`./section-modules/${someVariable}.js`)
.then(module => {
module.loadPageInto(main);
})
.catch(err => {
main.textContent = err.message;
});
- 使用 import 埋点
router.beforeEach(async (to, from) => {
try {
const phone = await getAppUserInfo(to)
await userStore.phoneLogin(params)
triggerAutoLogin(to, 'success', { phone }) // 抛出登录成功事件
return true
})
}catch (error) {}
// report.ts
*
* @param name {string} 页面名称, 文件夹名称 love 等
* @param type {string} 是否登录成功 success error
* @param res 数据
*/
export const triggerAutoLogin = async (to, type, res) => {
const module = await import(/* @vite-ignore */ `/src/views/Special/pages/${name}/config`)
const preData = module[dataType]
}
最后
如果有什么错误,欢迎指正~
网友评论