$id
$id
魔法属性可用于生成元素的 ID,并确保它不会与同一页面上的其他同名 ID 冲突。
在构建可能在页面上多次出现的可重用组件(大概在后端循环的模板中)并使用 ID 属性时,魔法属性 $id
将非常有用。
基本用法
如果在一个页面上有两个 input
输入框元素,期望它们渲染后各自拥有唯一的 ID,可以这样做:
html
<input x-data="" type="text" x-bind:id="$id('input')" />
<input x-data="" type="text" :id="$id('input')" />
html
<input x-data="" type="text" x-bind:id="$id('input')" id="input-1">
<input x-data="" type="text" :id="$id('input')" id="input-2">
组件渲染完后,$id
接受一个字符串并在页面上渲染唯一的 ID。
使用 $id 分组
假设想要拥有两个相同的输入元素,但这次添加 <label>
标签并且标签的 for
值跟输入框的 ID 值保持一致。
一种写法是调用魔术属性 $id
获取唯一 ID 值并存储在 x-data
中。
html
<label x-data="{ id: $id('input') }" :for="id">
<input type="text" :id="id">
</label>
<label x-data="{ id: $id('input') }" :for="id">
<input type="text" :id="id">
</label>
html
<label x-data="{ id: $id('input') }" :for="id" for="input-1">
<input type="text" :id="id" id="input-1">
</label>
<label x-data="{ id: $id('input') }" :for="id" for="input-2">
<input type="text" :id="id" id="input-2">
</label>
上面的方法必须在组件范围内命名和存储 ID 感觉很麻烦。
为了以更灵活的完成同样的任务,可以配合 Alpine 中的 x-id
指令一同使用。
html
<div x-data="" x-id="['text-input']">
<label :for="$id('text-input')">Username</label>
<input type="text" :id="$id('text-input')">
</div>
<div x-data="" x-id="['text-input']">
<label :for="$id('text-input')">Username</label>
<input type="text" :id="$id('text-input')">
</div>
html
<div x-data="" x-id="['text-input']">
<label :for="$id('text-input')" for="text-input-1">Username</label>
<input type="text" :id="$id('text-input')" id="text-input-1">
</div>
<div x-data="" x-id="['text-input']">
<label :for="$id('text-input')" for="text-input-2">Username</label>
<input type="text" :id="$id('text-input')" id="text-input-2">
</div>
x-id
接受一个 ID 名称数组。在该范围内的任何用法都将使得 $id()
生成相同的 ID。
嵌套
可以自由地嵌套这些 x-id
组,如下所示
html
<div x-data="" x-id="['text-input']">
<label :for="$id('text-input')">
<input :id="$id('text-input')" type="text">
</label>
<div x-id="['text-input']">
<label :for="$id('text-input')">
<input :id="$id('text-input')" type="text">
</label>
</div>
</div>
html
<div x-data="" x-id="['text-input']">
<label :for="$id('text-input')" for="text-input-1">
<input :id="$id('text-input')" type="text" id="text-input-1">
</label>
<div x-id="['text-input']">
<label :for="$id('text-input')" for="text-input-2">
<input :id="$id('text-input')" type="text" id="text-input-2">
</label>
</div>
</div>
循环 ID
有时运行循环逻辑时,在 ID 的末尾指定一个额外的后缀会很有帮助。
为此,$id()
接收可选的第二个参数,该参数将作为后缀添加到生成的 ID 的末尾。
html
<ul
x-data="{items: [{id: 1}, {id: 2}, {id: 3}]}"
x-id="['list-item']"
>
<template :key="item.id" x-for="item in items">
<li :id="$id('list-item', item.id)">...</li>
</template>
</ul>
html
<ul x-data="{items: [{id: 1}, {id: 2}, {id: 3}]}" x-id="['list-item']">
<template :key="item.id" x-for="item in items">
<li :id="$id('list-item', item.id)">...</li>
</template>
<li :id="$id('list-item', item.id)" id="list-item-1-1">...</li>
<li :id="$id('list-item', item.id)" id="list-item-1-2">...</li>
<li :id="$id('list-item', item.id)" id="list-item-1-3">...</li>
</ul>
可以看到渲染后,生成的列表的ID前缀是 list-item-1
,后面包含 items
属性的 id,以确保 li 列表的 ID 是唯一的。