You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Alpine JS结合Laravel Livewire:template标签x-transition失效的解决方法

解决AlpineJS x-transition 在分页列表中不生效的问题

问题核心在于<template>标签是Alpine的模板占位符,不会被渲染为实际DOM元素,因此内部的x-transition无法触发元素的插入/移除过渡。解决思路是将当前页的所有条目包裹在一个实际DOM容器中,利用x-key强制容器重新渲染,从而触发过渡效果。

修改后的代码:

<?php
$products = [
    [
        'url' => 'https://source.unsplash.com/featured/300x201',
        'title' => 'ITEM ONE'
    ],
    [
        'url' => 'https://source.unsplash.com/featured/300x202',
        'title' => 'ITEM TWO'
    ],
    [
        'url' => 'https://source.unsplash.com/featured/300x203',
        'title' => 'ITEM THREE'
    ],
    [
        'url' => 'https://source.unsplash.com/featured/300x204',
        'title' => 'ITEM FOUR'
    ],
    [
        'url' => 'https://source.unsplash.com/featured/300x205',
        'title' => 'ITEM FIVE'
    ],
    [
        'url' => 'https://source.unsplash.com/featured/300x206',
        'title' => 'ITEM SIX'
    ],
    [
        'url' => 'https://source.unsplash.com/featured/300x206',
        'title' => 'ITEM SEVEN'
    ],
    [
        'url' => 'https://source.unsplash.com/featured/300x207',
        'title' => 'ITEM EIGHT'
    ],
    [
        'url' => 'https://source.unsplash.com/featured/300x208',
        'title' => 'ITEM NINE'
    ],
    [
        'url' => 'https://source.unsplash.com/featured/300x209',
        'title' => 'ITEM TEN'
    ]
];
?>

<div x-data="{
    items: @js($products),
    currentPage: 0,
    perPage: 3
}" x-init="
    totalPages = Math.ceil(items.length / perPage)
">
    <!-- 包裹当前页条目,用x-key强制重新渲染,触发过渡 -->
    <div 
        x-key="currentPage"
        x-transition:enter="transition ease-out duration-300"
        x-transition:enter-start="opacity-0 transform scale-95"
        x-transition:enter-end="opacity-100 transform scale-100"
        x-transition:leave="transition ease-in duration-200"
        x-transition:leave-start="opacity-100 transform scale-100"
        x-transition:leave-end="opacity-0 transform scale-95"
        class="grid grid-cols-3 gap-4"
    >
        <template x-for="(item, index) in items.slice(currentPage * perPage, (currentPage + 1) * perPage)" :key="index">
            <div>
                <img :src="item.url" alt="" class="w-full">
                <p x-text="item.title" class="text-center mt-2"></p>
            </div>
        </template>
    </div>

    <div class="mt-6 flex gap-2">
        <button 
            x-show="currentPage > 0" 
            x-on:click="currentPage -= 1"
            class="px-4 py-2 bg-gray-200 rounded"
        >
            PREV
        </button>

        <button 
            x-show="(currentPage + 1) * perPage < items.length" 
            x-on:click="currentPage += 1"
            class="px-4 py-2 bg-gray-200 rounded"
        >
            NEXT
        </button>
    </div>
</div>

关键修改点:

  • 新增currentPage和perPage变量,简化分页逻辑,避免手动维护startIndex和endIndex
  • 将当前页的所有条目包裹在一个<div>容器中,给容器添加x-key="currentPage":当页码变化时,Alpine会销毁旧容器并创建新容器,触发x-transition
  • 自定义过渡动画(可按需调整),替代默认x-transition让效果更直观
  • 优化分页按钮的显示条件,逻辑更清晰

内容的提问来源于stack exchange,提问作者thairish

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 16:42:01