Alpine前端组件如何写?
官网是强烈推荐使用SSR来处理组件。
下面提供两个方案供参考。
Morph
官网提供了一个Morph的工具,可以用来实现组件化功能。
首先,在原本引入alpine的地方,上方添加此插件,如下:
<script src="libs/alpine.morph.min.js" defer></script>
<script src="libs/alpine.min.js" defer></script>
<script defer src="components/sc-loading.js"></script>
cdn链接为CDN,将其下载到自己服务器上,确保国内用户正常使用。
上面的sc-loading.js就是组件代码了。
组件这样写:
Alpine.morph(
document.querySelector('sc-loading'),
`
<div class="fixed top-0 left-0 w-full h-full bg-gray-900 bg-opacity-50 z-50 flex items-center justify-center" x-show="isLoading" x-transition>
<span class="loading loading-ring loading-lg"></span>
</div>
`
)
这是一个loading的组件,使用的是TailwindCSS。
可以看到,这里面可以直接使用相同作用域下的alpine变量,如isLoading,这个isLoading定义在对应的HTML结构上即可。
HTML结构如下:
<div x-data="indexData">
...
<sc-loading></sc-loading>
</div>
indexData:
Alpine.data('indexData', () => ({
isLoading: false,
}))
业务处理
业务处理就很简单了,正常处理即可,无需多余关注。
this.isLoading = true
this.isLoading = false
自定义指令
使用示例参考:
Alpine.directive('loadmore', (el, { expression }, { evaluateLater }) => { const _fn = evaluateLater(expression) let isLoading = false let lastScrollTime = 0 const THROTTLE_DELAY = 200 el.addEventListener('scroll', () => { const now = Date.now() if (now - lastScrollTime < THROTTLE_DELAY || isLoading) { return } const scrollBottom = el.scrollHeight - el.scrollTop - el.clientHeight if (scrollBottom <= 50) { isLoading = true lastScrollTime = now _fn().finally(() => { isLoading = false }) } })})
<divx-loadmore="onLoadMore"></div>
这个讲起来非常麻烦,但是优点就是可定制性非常高,具体描述可以参考相关文档,我这里大致说一些注意点。
其中参数说明:
el,就是挂载的 element,没啥好说的。
expression,就是指令后面跟着的表达式,由于可以是变量也可以是函数,所以可以使用 evaluateLater 来处理。
evaluateLater,一个将表达式转为函数的工具,转为的函数分两种,一种是返回了传入的表达式函数,一种是返回了生成表达式变量的函数。返回表达式的函数,当做表达式使用即可。而返回了变量函数的,则需要搭配 effect 使用实现监听效果,这个看下文档吧。
使用template标签
最简单,但是扩展麻烦。
<script>
const t = document.createElement('template')
t.innerHTML = `<div x-data="{ ppp: '123' }"><p x-text="ppp"></p></div>`
document.body.appendChild(t.content)
</script>