是否可以在 alpineJS 中引用外部 js 文件的代码?
Is it possible to reference code from an external js file in alpineJS?
我有一个 Alpine JS 模板,我想从数组中引用 x-data
。我目前在 HTML 文件底部的 <script>
标记中声明了它,我想将它移动到外部文件中。如果我使用 <script src='path/to/file.js'>
创建文件并 link 它,我的组件将停止工作。
有效示例:
<div x-data="{items}">
<template x-for="(item, index) in items" :key="index">
<a :href="item.link" x-text="item.text"></a>
</template>
</div>
<script>
const items = [
{ link: 'foo.com', text: 'foo' },
{ link: 'bar.com', text: 'bar' },
]
</script>
无效的示例,其中 external.js
具有相同的变量赋值
<div x-data="{items}">
<template x-for="(item, index) in items" :key="index">
<a :href="item.link" x-text="item.text"></a>
</template>
</div>
<script src="external.js"></script>
以及external.js文件的内容:
import 'alpinejs'
window.onload = () => {
console.log('loaded') // This logs in the console
var items = [
{ link: 'foo.com', text: 'foo' },
{ link: 'bar.com', text: 'bar' },
]
}
我不确定我做错了什么,帮助:(
好的,所以您的问题是您在侦听 window.onload
事件的回调中创建 items
变量。 AlpineJs 将已经加载并尝试解析 DOM,包括在事件触发和定义变量之前包含您的变量。
我们可以通过在 Alpine 组件的 x-init
属性中添加 console.log
来查看加载顺序:
<div x-data="{}" x-init="console.log('init')"></div>
<script>
window.onload = () => {
console.log('loaded')
}
</script>
有了这个,这就是我们在开发工具中得到的(工作示例 https://jsfiddle.net/hfm7p2a6/):
解决方案
解决这个问题在一定程度上取决于您需要在 items
中做什么。如果没有正在加载的动态内容(即您不需要执行 ajax 调用来获取数组的内容),那么只需忘记 onload
并将变量放在脚本文件(工作示例https://jsfiddle.net/nms7v4xh/):
// external.js
var items = ['your', 'items', 'array'];
// No window.onload needed
如果您确实需要其中包含动态内容,则需要将其注入到 AlpineJs 实例中。此处执行此操作的最佳方法可能是通过自定义事件(工作示例 https://jsfiddle.net/6dLwqn4g/1/):
<div id="app" x-data="{items: null}" @my-event.window="items = $event.detail.items"></div>
<script>
// Create and dispatch the event
let event = new CustomEvent('my-event', {
detail: {
items: ['your', 'dynamic', 'items', 'content']
}
});
window.dispatchEvent(event);
</script>
这里我们使用 AlpineJs 通过 @my-event.window
属性监听 window 上的事件(您也可以使用 x-on:my-event.window
)。然后我们可以通过 $event.detail
属性.
获取项目数据
希望对您有所帮助!如果需要,请阅读下面的一些额外内容。
https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent
我有一个 Alpine JS 模板,我想从数组中引用 x-data
。我目前在 HTML 文件底部的 <script>
标记中声明了它,我想将它移动到外部文件中。如果我使用 <script src='path/to/file.js'>
创建文件并 link 它,我的组件将停止工作。
有效示例:
<div x-data="{items}">
<template x-for="(item, index) in items" :key="index">
<a :href="item.link" x-text="item.text"></a>
</template>
</div>
<script>
const items = [
{ link: 'foo.com', text: 'foo' },
{ link: 'bar.com', text: 'bar' },
]
</script>
无效的示例,其中 external.js
具有相同的变量赋值
<div x-data="{items}">
<template x-for="(item, index) in items" :key="index">
<a :href="item.link" x-text="item.text"></a>
</template>
</div>
<script src="external.js"></script>
以及external.js文件的内容:
import 'alpinejs'
window.onload = () => {
console.log('loaded') // This logs in the console
var items = [
{ link: 'foo.com', text: 'foo' },
{ link: 'bar.com', text: 'bar' },
]
}
我不确定我做错了什么,帮助:(
好的,所以您的问题是您在侦听 window.onload
事件的回调中创建 items
变量。 AlpineJs 将已经加载并尝试解析 DOM,包括在事件触发和定义变量之前包含您的变量。
我们可以通过在 Alpine 组件的 x-init
属性中添加 console.log
来查看加载顺序:
<div x-data="{}" x-init="console.log('init')"></div>
<script>
window.onload = () => {
console.log('loaded')
}
</script>
有了这个,这就是我们在开发工具中得到的(工作示例 https://jsfiddle.net/hfm7p2a6/):
解决方案
解决这个问题在一定程度上取决于您需要在 items
中做什么。如果没有正在加载的动态内容(即您不需要执行 ajax 调用来获取数组的内容),那么只需忘记 onload
并将变量放在脚本文件(工作示例https://jsfiddle.net/nms7v4xh/):
// external.js
var items = ['your', 'items', 'array'];
// No window.onload needed
如果您确实需要其中包含动态内容,则需要将其注入到 AlpineJs 实例中。此处执行此操作的最佳方法可能是通过自定义事件(工作示例 https://jsfiddle.net/6dLwqn4g/1/):
<div id="app" x-data="{items: null}" @my-event.window="items = $event.detail.items"></div>
<script>
// Create and dispatch the event
let event = new CustomEvent('my-event', {
detail: {
items: ['your', 'dynamic', 'items', 'content']
}
});
window.dispatchEvent(event);
</script>
这里我们使用 AlpineJs 通过 @my-event.window
属性监听 window 上的事件(您也可以使用 x-on:my-event.window
)。然后我们可以通过 $event.detail
属性.
希望对您有所帮助!如果需要,请阅读下面的一些额外内容。
https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent