来自 reactive() 的 Vue3/Vuex 对象一旦在突变中作为有效负载传递给 vuex,就会失去反应性
Posted
技术标签:
【中文标题】来自 reactive() 的 Vue3/Vuex 对象一旦在突变中作为有效负载传递给 vuex,就会失去反应性【英文标题】:Vue3/Vuex Object from reactive() looses reactivity once passed as payload in mutation to vuex 【发布时间】:2021-09-11 16:41:46 【问题描述】:我知道,或者我不知道,但有些人可能会摸不着头脑,比如“为什么你想要一个可以与提供/注入到你的 Vuex 商店中使用的反应性对象?” ...好吧,因为我可以而且我必须'...
好吧,爸爸开玩笑,我有这个实现身份验证的插件,一旦安装到应用程序中,我会执行“穴居人风格”vuex 插件功能,将其注册到我的 vuex 商店的 namespaced 用户模块中,通过调用突变并传递反应性 const 对象 User
,它被包装在 Vue 3 的 reactive
函数中,作为有效负载。现在有趣的是,一旦注册到商店,它就会失去反应性,而提供/注入仍然可以正常工作:)
这里有一些意大利面:
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;
...
store/modules/User/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;
【问题讨论】:
【参考方案1】:实际上通过将有效负载传递为ToRefs(payload)
并使用Vue 提供的通用ToRef 键入它(如ToRefs<IAuthState>
)来实现我的目标。
我不确定这是否是最好的方法,但会为任何人留下空间,或者我是否设法找到更好的东西:)
【讨论】:
以上是关于来自 reactive() 的 Vue3/Vuex 对象一旦在突变中作为有效负载传递给 vuex,就会失去反应性的主要内容,如果未能解决你的问题,请参考以下文章
为啥 router.push 不起作用? [Vue 3] [Vuex 4]
Vite2+TypeScript4+Vue3+vuex4+vueRouter4+elementPlus如何入手开发新项目