【发布时间】:2020-09-29 13:18:28
【问题描述】:
在我们使用 Vue 2.x 的生产应用程序中,我们有一个 toast 组件。这个 toast 组件通过插件(下面的代码)安装一次,然后添加到 Vue 原型中,使其在每个组件实例中都可以访问。
这让生活变得更轻松,而不必在我们使用的任何地方添加吐司。
Vue 2.x 插件
export default {
install(vue: any, _: any) {
const root = new Vue({ render: (createElement) => createElement(Toast) });
root.$mount(document.body.appendChild(document.createElement("div")));
const toastInstance: Toast = root.$children[0] as Toast;
vue.prototype.$toast = {
show: (state: ToastState, text: string) => { toastInstance.show(state, text); },
hide: () => { toastInstance.hide(); }
};
}
然后可以在任何组件中调用,例如:
this.$toast.show(ToastStates.SUCCESS, "Some success message");
我最近开始了另一个项目,想做类似的事情,除了使用 Vue 3。因为我们无法访问 setup 函数中的 this,所以我无法使用与以前相同的方法.
我一直在研究一些事情,并找到了一些方法,但没有一个是确定的最佳实践。
提供/注入: 这似乎是最有希望的,我可以在哪里使用
export const appInstance = createApp(App);
然后
appInstance.provide("toast", toastComponentInstance)
然后我可以将其注入任何组件。这样做的问题是,要使其在每个组件中可用,它需要附加到尚未创建的初始应用程序实例。也许我可以手动挂载它并传递它(但这似乎是一种黑客行为)。
组成: 我也在这里查看了这个问题:How to access root context from a composition function in Vue Composition API / Vue 3.0 + TypeScript? 但没有发现它很有用,我不得不做所有类型的黑客才能真正获得对插件的访问权限。总代码如下..
export function useToast() {
const root = getCurrentInstance();
const openToast: (options: ToastOptions) => void = (options: ToastOptions) => {
root.ctz.$toast.open(options);
}
const closeToast: () => void = () => {
root.ctx.$toast.close();
}
return {
openToast,
closeToast
}
}
我还有其他想法,但它们似乎有点牵强。热衷于听取人们对其他解决方案的想法。我只想要一个简单的方法来拥有一个 toast 实例,我可以调用两个函数来在我想要的时间和地点打开/关闭它。
【问题讨论】:
-
只是一般的观察,您似乎在与“Vue 方式”作斗争。与其接触子级来执行一个方法……为什么不在父级中提供一个简单的状态变量,然后对下游状态的变化做出反应?
标签: vue.js vuejs3 vue-composition-api