Laravel 8搭配Inertia.js与Vue3如何定义全局变量共享给所有组件?
错误原因说明
- 全局属性挂载失败:
createInertiaApp的setup回调参数里的app是Inertia的根组件配置对象,不是Vue3的应用实例,你需要操作的是createApp()调用后返回的Vue实例对象。 - Provide/Inject注入失败:你使用选项式
provide时直接访问this.toast,但setup执行阶段Vue实例还未完成初始化,this指向为空,且组合式API的provide必须写在setup函数内部才能生效。
可行实现方案
方案1:正确挂载Vue全局属性
修改app.js里的setup逻辑,先拿到Vue应用实例再挂载全局属性:
createInertiaApp({ title: (title) => `${title} - ${appName}`, resolve: (name) => require(`./Pages/${name}.vue`), setup({ el, app, props, plugin }) { // 初始化Vue应用实例 const vueApp = createApp({ render: () => h(app, props) }); // 先注册所有插件 vueApp.use(Toast) .use(plugin) .mixin({ methods: { route } }); // 注册完成后挂载全局toast属性 vueApp.config.globalProperties.$toast = useToast(); // 挂载应用 return vueApp.mount(el); }, });
组件内调用方式:
- 选项式API:直接通过
this.$toast.success('提示内容')调用 - 组合式API:通过
getCurrentInstance获取实例代理调用:import { getCurrentInstance } from 'vue' const { proxy } = getCurrentInstance() proxy.$toast.success('提示内容')
方案2:根级别Provide注入
直接在应用根层级注入toast,所有子孙组件都可以直接获取:
// app.js顶部先导入provide import { createApp, h, provide } from "vue"; createInertiaApp({ title: (title) => `${title} - ${appName}`, resolve: (name) => require(`./Pages/${name}.vue`), setup({ el, app, props, plugin }) { const vueApp = createApp({ render: () => h(app, props) }); vueApp.use(Toast) .use(plugin) .mixin({ methods: { route } }); // 根层级注入toast const toast = useToast(); provide('toast', toast); return vueApp.mount(el); }, });
组件内调用方式:
- 选项式API:声明
inject: ['toast']后直接通过this.toast调用 - 组合式API:直接导入
inject获取:import { inject } from 'vue' const toast = inject('toast') toast.success('提示内容')
方案3:AppLayout层级Provide修正
如果你希望在布局层注入而不是全局注入,修正你的原有写法即可:
<script> import { provide } from 'vue' import { useToast } from "vue-toastification"; export default { setup() { const toast = useToast(); // 在setup内部调用provide注入 provide('toast', toast) return { toast }; } } </script>
子组件声明inject: ['toast']即可正常获取,不会再报注入不存在的错误。
补充推荐用法
vue-toastification在全局注册完成后,所有组件内可以直接调用useToast()获取实例,不需要额外做全局共享配置,是官方更推荐的轻量用法。
内容的提问来源于stack exchange,提问作者Enes
相关产品推荐
相关产品推荐

