跳到主要内容

列表渲染

OpenInula 提供了内置的 for 标签来实现列表渲染,使得数组的遍历和渲染变得简单直观。

基本用法

简单列表

使用 for 标签遍历数组:

function FruitList() {
const fruits = ['苹果', '香蕉', '橙子'];

return (
<ul>
<for each={fruits}>
{(fruit) => <li>{fruit}</li>}
</for>
</ul>
);
}

带索引的列表

通过第二个参数获取索引:

function NumberedList() {
const items = ['第一项', '第二项', '第三项'];

return (
<ul>
<for each={items}>
{(item, index) => (
<li>#{index + 1}: {item}</li>
)}
</for>
</ul>
);
}

对象列表

渲染对象数组:

function UserList() {
const users = [
{ id: 1, name: '张三', age: 25 },
{ id: 2, name: '李四', age: 30 },
{ id: 3, name: '王五', age: 28 }
];

return (
<table>
<thead>
<tr>
<th>ID</th>
<th>姓名</th>
<th>年龄</th>
</tr>
</thead>
<tbody>
<for each={users}>
{(user) => (
<tr>
<td>{user.id}</td>
<td>{user.name}</td>
<td>{user.age}</td>
</tr>
)}
</for>
</tbody>
</table>
);
}

列表操作

列表过滤

可以在渲染前对列表进行过滤:

function ActiveUserList() {
const users = [
{ id: 1, name: '张三', active: true },
{ id: 2, name: '李四', active: false },
{ id: 3, name: '王五', active: true }
];

const activeUsers = users.filter(user => user.active);

return (
<ul>
<for each={activeUsers}>
{(user) => <li>{user.name}</li>}
</for>
</ul>
);
}

列表排序

可以在渲染前对列表进行排序:

function SortedUserList() {
const users = [
{ id: 1, name: '张三', age: 25 },
{ id: 2, name: '李四', age: 30 },
{ id: 3, name: '王五', age: 28 }
];

const sortedUsers = [...users].sort((a, b) => a.age - b.age);

return (
<ul>
<for each={sortedUsers}>
{(user) => (
<li>{user.name} ({user.age}岁)</li>
)}
</for>
</ul>
);
}

嵌套列表

可以嵌套使用 for 标签:

function NestedList() {
const departments = [
{
name: '技术部',
teams: ['前端组', '后端组', '测试组']
},
{
name: '产品部',
teams: ['设计组', '运营组']
}
];

return (
<div>
<for each={departments}>
{(dept) => (
<div>
<h3>{dept.name}</h3>
<ul>
<for each={dept.teams}>
{(team) => <li>{team}</li>}
</for>
</ul>
</div>
)}
</for>
</div>
);
}

最佳实践

1. 列表项组件化

对于复杂的列表项,建议将其抽取为单独的组件:

function UserItem({ user }) {
return (
<div className="user-item">
<img src={user.avatar} alt={user.name} />
<div className="user-info">
<h3>{user.name}</h3>
<p>{user.email}</p>
</div>
</div>
);
}

function UserList() {
const users = [/* ... */];

return (
<div className="user-list">
<for each={users}>
{(user) => <UserItem user={user} />}
</for>
</div>
);
}

2. 列表更新优化

当列表项可能发生变化时,建议使用不可变数据操作:

function TodoList() {
let todos = [
{ id: 1, text: '学习 OpenInula', done: false },
{ id: 2, text: '写文档', done: false }
];

function toggleTodo(id) {
todos = todos.map(todo =>
todo.id === id
? { ...todo, done: !todo.done }
: todo
);
}

return (
<ul>
<for each={todos}>
{(todo) => (
<li
onClick={() => toggleTodo(todo.id)}
style={{ textDecoration: todo.done ? 'line-through' : 'none' }}
>
{todo.text}
</li>
)}
</for>
</ul>
);
}

注意事项

  1. for 标签必须包含 each 属性
  2. 回调函数必须返回 JSX 元素
  3. 对于大列表,考虑使用分页或虚拟滚动
  4. 避免在渲染函数中进行复杂计算,建议提前处理数据

下一步

学习完列表渲染后,你可以:

  1. 了解事件处理系统
  2. 探索组件组合的技巧
  3. 学习状态管理的最佳实践

欢迎关注openInula微信公众号