使用 Vue 3 在 InertiaJS 中定义全局组件
Posted
技术标签:
【中文标题】使用 Vue 3 在 InertiaJS 中定义全局组件【英文标题】:Define global component in InertiaJS with Vue 3 【发布时间】:2021-08-05 05:02:26 【问题描述】:我正在尝试在 Laravel 8.38 - InertiaJS 0.8.4
上构建一个应用程序,我正在使用 Vue 3
作为我的前端堆栈。
我有多个布局需要全局注册为Vue
组件,以便我可以在任何地方的应用程序中使用它。我做不到,我的代码:
import createApp, h from 'vue';
import App as InertiaApp, plugin as InertiaPlugin from '@inertiajs/inertia-vue3';
const el = document.getElementById('app');
const app = createApp(
render: () =>
h(InertiaApp,
initialPage: JSON.parse(el.dataset.page),
resolveComponent: (name) => require(`./../Pages/$name`).default,
),
)
.mixin( methods: route )
.use(InertiaPlugin);
app.component('app-market', () => import('./../layouts/AppMarketLayout')); //trying to import layout
app.mount(el);
在页面内部我试图调用这个布局组件:
<template>
<div>
<app-market-layout></app-market-layout>
</div>
</template>
无法获取,控制台中没有错误。
【问题讨论】:
您注册了一个app-market
组件,但您的标记使用了app-market-layout
。
【参考方案1】:
我有 2 个用于后端(管理面板)和前端(网站)的布局,实现如下。使用惯性默认中间件文件。
项目/app/Http/Middleware/HandleInertiaRequests.php
class HandleInertiaRequests extends Middleware
protected $rootView = 'app';
public function rootView(Request $request)
if ($request->segment(1) == 'admin')
return 'admin';
return parent::rootView($request);
public function version(Request $request)
return parent::version($request);
public function share(Request $request)
return array_merge(parent::share($request), [
//
]);
project/resources/js/Shared/Frontend/Layouts/Layout.vue
<template>
<Header />
<slot />
<Footer />
</template>
<script>
import Header from '../Partials/Header'
import Footer from '../Partials/Footer'
export default
components:
Header,
Footer
,
name: "FrontendLayout"
</script>
project/resources/js/Pages/Frontend/Auth/Login.vue
<template>
...
</template>
<script>
import Layout from '@/js/Shared/Frontend/Layouts/Layout';
export default
layout: Layout,
metaInfo: title: 'Login' ,
data()
return
form: this.$inertia.form(
'email': '',
'password': '',
'remember': false
)
,
methods:
submit()
this.form.post(route('login.store'))
</script>
【讨论】:
【参考方案2】:在 Inertia JS 中,全局导入组件与使用普通 Vue 配置相同。
在您的 app.js 文件中,您需要导入组件(内联或文件顶部),然后在挂载 vue 实例之前添加组件。 You can either do this as a mixin, or as a component.
因此,在您的情况下,配置应如下所示:
import createApp, h from 'vue';
import App as InertiaApp, plugin as InertiaPlugin from '@inertiajs/inertia-vue3';
//Import the component:
import AppMarket from "./../layouts/AppMarketLayout";
const el = document.getElementById('app');
const app = createApp(
render: () =>
h(InertiaApp,
initialPage: JSON.parse(el.dataset.page),
resolveComponent: (name) => require(`./../Pages/$name`).default,
),
)
.mixin( methods: route )
.mixin( components: AppMarket ) // << Then tell the inertia
// instance to use the component.
// You can also add this to the other mixin declaration
.use(InertiaPlugin)
.mount(el);
然后,在您的模板中,您可以像这样使用组件:
<template>
<app-market>
</app-market>
</template>
我在您的原始帖子中注意到您正在尝试将该组件用作应用市场布局。如果您打算这样做,则必须导入具有该名称的组件。
app.js 中的配置如下所示:
import createApp, h from 'vue';
import App as InertiaApp, plugin as InertiaPlugin from '@inertiajs/inertia-vue3';
//Import the component: Notice the component name change.
import AppMarketLayout from "./../layouts/AppMarketLayout";
const el = document.getElementById('app');
const app = createApp(
render: () =>
h(InertiaApp,
initialPage: JSON.parse(el.dataset.page),
resolveComponent: (name) => require(`./../Pages/$name`).default,
),
)
.mixin( methods: route )
.mixin( components: AppMarketLayout ) // << Here the component name has Layout
.use(InertiaPlugin)
.mount(el);
然后在你的模板中:
<template>
<app-market-layout>
</app-market-layout>
</template>
【讨论】:
以上是关于使用 Vue 3 在 InertiaJS 中定义全局组件的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Laravel InertiaJS 中使用 VueJS 配置 Tailwind + Postcss
如何使用 Laravel 8、Inertia.js 和 Vue3 定义全局变量?