typescript - 来自 reactive() 的 Vue3/Vuex 对象一旦在突变中作为有效负载传递给 vuex,就会失去反应性
问题描述
我知道,或者我不知道,但有些人可能会摸不着头脑,比如“为什么你想要一个可以与提供/注入到你的 Vuex 商店中使用的反应性对象?” ...好吧,因为我可以而且我必须'...
好吧,爸爸开玩笑说我有这个实现身份验证的插件,一旦安装到应用程序中,我会执行一个“穴居人风格”vuex 插件函数,通过调用突变并传递反应性常量,将其注册到我的 vuex 商店的命名空间用户模块中object User
,包装在reactive
Vue 3 的函数中,作为有效负载。现在有趣的是,一旦注册到商店,它就会失去反应性,而提供/注入仍然可以正常工作:)
这里有一些意大利面:
AuthLink.vue
...
export default defineComponent({
setup() {
const auth = inject("Auth") as IAuthPluginProperties;
async function logInFromLink(
withPopUp = false,
options?: {
redirectLoginOptions?: RedirectLoginOptions;
popupConfigOptions?: PopupConfigOptions;
analytics: undefined;
}
): Promise<void> {
if (withPopUp) return auth.loginWithPopup();
//* Potentially add analytics for how many people logged in with the link, from which page etc.
return await auth.loginWithRedirect(options?.redirectLoginOptions);
}
function logout(logoutOptions?: LogoutOptions): void {
auth.logout(logoutOptions);
}
return {
auth,
logInFromLink,
logout
};
}
});
</script>
插件 - index.ts
...
export default {
install: async (app: App, options: pluginInstallOptions): Promise<void> => {
app.config.globalProperties.$auth = Plugin.AuthPluginProperties;
app.provide("Auth", Plugin.AuthPluginProperties);
/*
* Could Handle defaulting to.env vars
* & then -> if !env vars throw err
*/
if (options.useStore) {
if (!store.hasModule("User")) {
throw new Error(
" Something evil is lurking in the shadows...`User` vuex store module has not been registered."
).stack;
}
await vuexPlugin(store, Vue3AuthPlugin.AuthPluginProperties);
...
插件 - main.ts
...
const state = reactive({
isLoading: false,
isAuthenticated: false,
user: undefined,
popupOpen: false,
error: null
}) as IAuthStateProp;
export const AuthPluginProperties = reactive({
isAuthenticated: computed(() => state.isAuthenticated),
isLoading: computed(() => state.isLoading),
user: computed(() => state.user),
...some more functions passed here
}) as IAuthPluginProperties;
...
存储/模块/用户/Mutations.ts
import { MutationTree } from "vuex";
import { UserMutations, UserMutationTypes, UserState } from "@/store/types";
import IAuthPluginProperties from "~interfaces/Auth/IAuthPluginProperties";
const mutations: MutationTree<UserState> & UserMutations = {
[UserMutationTypes.INITIALIZE_PLUGIN](state: UserState, payload: IAuthPluginProperties) {
state.User = payload;
}
};
export default mutations;
[编辑 1]
忘记添加“穴居人风格”vuex插件功能的代码
auth-vuex-plugin.ts
import { AuthVuexPlugin } from "../types";
const plugin: AuthVuexPlugin<Record<string, unknown>> = async (store, payload) => {
try {
await store.dispatch("User/INITIALIZE_PLUGIN", payload);
} catch (err) {
throw new Error(` Something evil happened... Vuex init failed: ${err}`);
}
};
export default plugin;
解决方案
ToRefs(payload)
实际上通过传递有效负载以及使用 Vue 提供的通用 ToRef 键入它来实现我所追求的,例如ToRefs<IAuthState>
.
我不确定这是否是最好的方法,但会为任何人留下空间,或者我是否设法找到更好的东西:)
推荐阅读
- encryption - 端到端加密静态网站内容
- python - Python lowriter 调用获得与终端不同的结果
- lammps - Windows 10 AMMPS 更改 DocumentRoot
- google-apps-script - 谷歌表格自动过滤器
- c - 给定时间戳,批量混合音频。多个偏移,只有两个声音。如何有效地做到这一点?
- plsql-psp - 带有大小写条件的 pl/sql 日期过滤器
- javascript - 无法按整数值对对象数组进行排序
- python - 在文件中看不到 csv 文件(从 df 转换而来)
- python - 无需登录即可从 url 验证 Django
- r - 将“NA”字符串更改为 -99.99