英文:
Issue Using Alpine.js with Vite in a fresh Laravel 10 installation
问题
I've translated the non-code part of your content:
我一直在尝试首次使用Vite,我更熟悉Laravel Mix。当我在app.js中包含Alpine函数并使用npm run build
构建时,这些函数似乎无法从标记中的指令中运行。以下是我的代码:
在index.blade.php
中:
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8 grid grid-cols-1 md:grid-cols-3 gap-4" x-data="solar">
<form @submit.prevent="addComponent">
<div class="mt-4">
<x-select-input id="component" :items="$products->pluck('name', 'id')"></x-select-input>
</div>
<div class="mt-4">
<x-primary-button>Add Component</x-primary-button>
</div>
</form>
</div>
<div>
<ul class="w-96">
<template x-for="component in components">
<li class="w-full border-b-2 border-neutral-100 border-opacity-100 py-4 dark:border-opacity-50" x-text="component.name"></li>
</template>
</ul>
</div>
在app.js
中:
import './bootstrap';
import Alpine from 'alpinejs';
window.Alpine = Alpine;
Alpine.start();
document.addEventListener('alpine:init', () => {
Alpine.data('solar', () => ({
components: [],
addComponent(elem) {
let item = document.getElementById('component');
this.components.push({
id: item.value,
name: item.options[item.selectedIndex].text,
});
},
}));
});
在vite.config.js
中:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel({
input: [
'resources/css/app.css',
'resources/js/app.js',
],
refresh: true,
}),
],
});
如果在视图(index.blade.php)中的<script>
标签中包含相同的Alpine.data()
函数,它可以完美运行。但是,当它放在app.js中并包含在生成的构建中时,我会收到以下错误消息:
Alpine 表达式错误:addComponent 未定义
表达式:"addComponent"
如何解决这个问题并将我的函数放在 Vite 构建中而不是在视图中?
英文:
I've been attempting to use Vite for the first time, I'm more familiar with Laravel Mix. It appears that when I include alpine functions in app.js and build with npm run build
those functions cannot be run from the directives in the markup. Heres my code:
in index.blade.php
:
<div
class="max-w-7xl mx-auto sm:px-6 lg:px-8 grid grid-cols-1 md:grid-cols-3 gap-4"
x-data="solar"
>
<form @submit.prevent="addComponent">
<div class="mt-4">
<x-select-input id="component" :items="$products->pluck('name', 'id')"></x-select-input>
</div>
<div class="mt-4">
<x-primary-button>Add Component</x-primary-button>
</div>
</form>
</div>
<div>
<ul class="w-96">
<template x-for="component in components">
<li
class="w-full border-b-2 border-neutral-100 border-opacity-100 py-4 dark:border-opacity-50"
x-text="component.name" >
</li>
</template>
</ul>
</div>
in app.js
:
import './bootstrap';
import Alpine from 'alpinejs';
window.Alpine = Alpine;
Alpine.start();
document.addEventListener('alpine:init', () => {
Alpine.data('solar', () => ({
components: [],
addComponent(elem) {
let item = document.getElementById('component');
this.components.push({
id: item.value,
name: item.options[item.selectedIndex].text,
});
},
}));
});
And in vite.config.js
:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel({
input: [
'resources/css/app.css',
'resources/js/app.js',
],
refresh: true,
}),
],
});
If include the same Alpine.data()
function in a script tag within the view (index.blade.php), it works flawlessly: but when it's placed within app.js and included in the resulting build I get the error:
Alpine Expression Error: addComponent is not defined
Expression: "addComponent"
How can I solve this and put my functions in the Vite build instead of in the view?
答案1
得分: 1
以下是翻译好的内容:
如Alpine.js文档所述:
> 如果你将Alpine导入到一个捆绑包中,你必须确保在导入Alpine
全局对象时和调用Alpine.start()
初始化Alpine之间注册任何扩展代码。
对我来说,这似乎只是一个排序问题(我以前也遇到过相同的问题)。在所有的alpine.js代码之后调用Alpine.start()
。你的app.js
应该类似于这样:
import Alpine from 'alpinejs';
window.Alpine = Alpine;
Alpine.data('solar', () => ({ ... }));
Alpine.start();
请注意,在使用这样的构建系统时,你不需要'alpine:init'
事件监听器。查看文档中的这个部分以获取示例。我建议将所有的alpine.js组件从app.js
中提取到单独的文件中,以更好地分离关注点,并当你开始添加更多组件时,防止app.js
变得过于臃肿。类似这样:
// app.js
import Alpine from 'alpinejs';
window.Alpine = Alpine;
import component1 from './alpine_components/component1.js';
import component2 from './alpine_components/component2.js';
...
Alpine.data('component1', component1);
Alpine.data('component2', component2);
...
Alpine.start();
// alpine_components/component1.js
export default () => ({
...
});
英文:
As stated in the alpine.js docs:
> If you imported Alpine into a bundle, you have to make sure you are registering any extension code IN BETWEEN when you import the Alpine
global object, and when you initialize Alpine by calling Alpine.start()
.
To me it looks like this shouldn't be anything but just an ordering issue (I've had the same problem myself before). Call Alpine.start()
AFTER all of your alpine.js code. Your app.js
should look something like this:
import Alpine from 'alpinejs';
window.Alpine = Alpine;
Alpine.data('solar', () => ({ ... }));
Alpine.start();
Note that you don't need the 'alpine:init'
event listener when using a build system like this. Have a look at this section in the docs for an example. I'd recommend extracting all of your alpine.js components out of app.js
into individual files for better separation of concerns, and of course to prevent your app.js
from becoming too bloated when you start adding more components. Something like this:
// app.js
import Alpine from 'alpinejs';
window.Alpine = Alpine;
import component1 from './alpine_components/component1.js';
import component2 from './alpine_components/component2.js';
...
Alpine.data('component1', component1);
Alpine.data('component2', component2);
...
Alpine.start();
// alpine_components/component1.js
export default () => ({
...
});
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论