Alpine.js模板中Tailwind Grid单元格丢失问题求助
问题原因
Alpine.js 3.x 的 x-for 循环要求 <template> 标签内必须只有一个根元素。你的代码中每个循环返回了两个同级 <div>,Alpine 只会渲染第一个元素,因此用量单元格被丢弃。同时,x-for 循环需要添加 :key 属性来跟踪元素身份,这是 Alpine 3.x 的强制要求,避免渲染异常。
解决方案
以下两种方式都能解决问题,可根据需求选择:
方案一:包裹循环内的两个元素(保持原布局逻辑)
将每个食材的名称和用量单元格包裹在一个父容器中,确保 <template> 只有一个根元素,同时保留网格布局结构:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Simple Dough Recipe</title> <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet"> <script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script> </head> <body class="bg-purple-100"> <div x-data="recipe()" class="p-10"> <div class="grid grid-cols-2 gap-2"> <template x-for="ingredient in ingredients" :key="ingredient.name"> <!-- 用父容器包裹两个单元格,满足template单根元素要求 --> <div class="grid grid-cols-2 gap-2 w-full"> <div class="bg-red-700" x-text="ingredient.name">Ingredient</div> <div class="bg-green-700" x-text="ingredient.qty">Qty</div> </div> </template> </div> <div class="grid grid-cols-2 gap-2 mt-10"> <div class="bg-blue-700">Flour</div> <div class="bg-green-700">1000</div> <div class="bg-blue-700">Water</div> <div class="bg-green-700">600</div> <div class="bg-blue-700">Salt</div> <div class="bg-green-700">10</div> <div class="bg-blue-700">Yeast</div> <div class="bg-green-700">5</div> </div> </div> </body> <script> function recipe() { return { ingredients: [ {name: 'Flour', qty: 1000}, {name: 'Water', qty: 600}, {name: 'Salt', qty: 10}, {name: 'Yeast', qty: 5} ] } } </script> </html>
方案二:扁平化食材数组(完全匹配预期网格结构)
如果希望渲染结果和第二个手动编写的网格完全一致(每个单元格单独占据网格列),可以在数据中添加扁平化的计算属性,直接循环单个单元格:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Simple Dough Recipe</title> <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet"> <script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script> </head> <body class="bg-purple-100"> <div x-data="recipe()" class="p-10"> <div class="grid grid-cols-2 gap-2"> <template x-for="item in flatIngredients" :key="item"> <div x-text="item" :class="typeof item === 'string' ? 'bg-red-700' : 'bg-green-700'" ></div> </template> </div> <div class="grid grid-cols-2 gap-2 mt-10"> <div class="bg-blue-700">Flour</div> <div class="bg-green-700">1000</div> <div class="bg-blue-700">Water</div> <div class="bg-green-700">600</div> <div class="bg-blue-700">Salt</div> <div class="bg-green-700">10</div> <div class="bg-blue-700">Yeast</div> <div class="bg-green-700">5</div> </div> </div> </body> <script> function recipe() { return { ingredients: [ {name: 'Flour', qty: 1000}, {name: 'Water', qty: 600}, {name: 'Salt', qty: 10}, {name: 'Yeast', qty: 5} ], // 扁平化数组,将每个食材的name和qty拆分为独立项 get flatIngredients() { return this.ingredients.flatMap(ing => [ing.name, ing.qty]); } } } </script> </html>
内容的提问来源于stack exchange,提问作者Rodrigo Varela Tabuyo
相关产品推荐
相关产品推荐

