代码演示
如何引入
import { List } from '@kousum/semi-ui-vue';
基本用法
列表的基本用法。可以通过 size 设置尺寸,支持large
, default
, small
。可设置 header 和 footer,来自定义列表头部和尾部。
xxxxxxxxxx
import { List } from '@kousum/semi-ui-vue';
export default ()=>{
const data = [
'从明天起,做一个幸福的人',
'喂马,劈柴,周游世界',
'从明天起,关心粮食和蔬菜',
'我有一所房子,面朝大海,春暖花开',
];
return (
<div>
<div style={{ marginRight: '16px' }}>
<h3 style={{ marginBottom: '16px' }}>Default Size</h3>
<List
header={<div>Header</div>}
footer={<div>Footer</div>}
bordered
dataSource={data}
renderItem={item => <List.Item>{item}</List.Item>}
/>
</div>
<div style={{ marginRight: '16px' }}>
<h3 style={{ margin: '16px 0' }}>Small Size</h3>
<List
size="small"
header={<div>Header</div>}
footer={<div>Footer</div>}
模板用法
列表的 List.Item 内置了简单的结构包含:header,main 和 extra 。其中 header 和 main 的对齐方式可以通过 align 属性设置,支持 flex-start
(默认), flex-end
, center
, baseline
, 和 stretch
。
xxxxxxxxxx
import { List, Avatar, ButtonGroup, Button } from '@kousum/semi-ui-vue';
export default ()=>{
const data = [
// eslint-disable-next-line react/jsx-key
<p
style={{
color: 'var(--semi-color-text-2)',
margin: '4px 0',
width: '420px',
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
}}
>
Semi Design 是由抖音前端团队与 UED
团队共同设计开发并维护的设计系统。设计系统包含设计语言以及一整套可复用的前端组件,帮助设计师与开发者更容易地打造高质量的、用户体验一致的、符合设计规范的
Web 应用。
</p>,
// eslint-disable-next-line react/jsx-key
<p style={{ color: 'var(--semi-color-text-2)', margin: '4px 0', width: '500px' }}>
Semi Design 是由抖音前端团队与 UED
团队共同设计开发并维护的设计系统。设计系统包含设计语言以及一整套可复用的前端组件,帮助设计师与开发者更容易地打造高质量的、用户体验一致的、符合设计规范的
Web 应用。
</p>,
// eslint-disable-next-line react/jsx-key
布局
通过 layout 属性可以设置列表的布局,支持vertical
(默认)和horizontal
。
xxxxxxxxxx
import { List, Avatar } from '@kousum/semi-ui-vue';
export default ()=>{
const data = [
{
title: 'Semi Design Title 1',
color: 'light-blue',
},
{
title: 'Semi Design Title 2',
color: 'grey',
},
{
title: 'Semi Design Title 3',
color: 'light-green',
},
];
return (
<div style={{ padding: '12px', border: '1px solid var(--semi-color-border)', margin: '12px' }}>
<List
dataSource={data}
layout="horizontal"
renderItem={item => (
<List.Item
header={<Avatar color={item.color}>SE</Avatar>}
栅格列表
通过 grid 属性可以实现栅格列表,span
可设置每项的占格数,gutter
可设置栅格间隔。
xxxxxxxxxx
import { List, Descriptions, ButtonGroup, Rating, Button } from '@kousum/semi-ui-vue';
export default ()=>{
const data = [
{
title: '审核管理平台',
rating: 4.5,
feedbacks: 124,
},
{
title: '扁鹊',
rating: 4,
feedbacks: 108,
},
{
title: '直播审核平台',
rating: 4.5,
feedbacks: 244,
},
{
title: '抖音安全测试',
feedbacks: 189,
},
];
const style = {
响应式的栅格列表
响应式的栅格列表。响应尺寸与 Grid 保持一致。
xxxxxxxxxx
import { List, Descriptions, Rating, Button, ButtonGroup } from '@kousum/semi-ui-vue';
export default ()=>{
const data = [
{
title: '审核管理平台',
rating: 4.5,
feedbacks: 124,
},
{
title: '扁鹊',
rating: 4,
feedbacks: 108,
},
{
title: '直播审核平台',
rating: 3.5,
feedbacks: 244,
},
{
title: '抖音安全测试',
feedbacks: 189,
},
{
title: '内容平台',
rating: 3,
加载更多
可通过 loadMore 属性实现加载更多的功能。
xxxxxxxxxx
import { List, Skeleton, Button, Avatar } from '@kousum/semi-ui-vue';
import { defineComponent, onMounted, reactive } from 'vue';
const LoadMoreList = defineComponent(() => {
let count2 = 3;
let data = [];
for (let i = 0; i < 40; i++) {
data.push({
color: 'grey',
title: `Semi Design Title ${i}`,
loading: false,
});
}
const state = reactive({
loading: false,
dataSource: [],
list: [],
noMore: false,
});
let count = 0;
const fetchData = () => {
let placeholders = [0, 1, 2].map(key => ({ loading: true }));
滚动加载
可以通过集成 react-infinite-scroller 来实现滚动加载的列表。交互建议符合 semi 交互设计规范,这里采用三次滚加载后出现 load more 按钮的形式。
xxxxxxxxxx
import { List, Button, Avatar, Spin } from '@kousum/semi-ui-vue';
import InfiniteScroll from 'react-infinite-scroller';
class ScrollLoad extends React.Component {
constructor() {
super();
const count = 5;
const dataList = [];
for (let i = 0; i < 100; i++) {
dataList.push({
color: 'grey',
title: `Semi Design Title ${i}`,
loading: false,
});
}
this.data = dataList;
this.count = 0;
this.fetchData = () => {
this.setState({
loading: true,
});
return new Promise((res, rej) => {
setTimeout(() => {
let dataSource = this.data.slice(this.count * count, this.count * count + count);
res(dataSource);
}, 1000);
滚动加载无限长列表
可以通过集成 react-virtualized 实现滚动加载无限长列表,带有虚拟化(virtualization)功能,能够提高数据量大时候长列表的性能。
xxxxxxxxxx
import { List, Avatar } from '@kousum/semi-ui-vue';
import { InfiniteLoader, AutoSizer } from 'react-virtualized';
import VList from 'react-virtualized/dist/commonjs/List';
class VirtualizedScroll extends React.Component {
constructor() {
super();
const dataList = [];
for (let i = 0; i < 50; i++) {
dataList.push({
color: 'grey',
title: `Semi Design Title ${i}`,
});
}
this.data = dataList;
this.fetchData = (startIndex, stopIndex) => {
return new Promise((res, rej) => {
setTimeout(() => {
let dataSource = this.data.slice(startIndex, stopIndex + 1);
res(dataSource);
}, 1000);
}).then(dataSource => {
let newData = [this.state.dataSource, dataSource];
const { loadedRowsMap, loadingRowCount } = this.state;
const increment = stopIndex - startIndex + 1;
for (let i = startIndex; i <= stopIndex; i++) {
拖拽排序
可以通过集成 react-dnd 来实现拖拽排序。
xxxxxxxxxx
import { List, Avatar } from '@kousum/semi-ui-vue';
import { DndProvider, DragSource, DropTarget } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import ReactDOM from 'react-dom';
class DraggableItem extends React.Component {
render() {
const { component, draggingItem, index, connectDragSource, connectDropTarget } = this.props;
const opacity = draggingItem && draggingItem.index === index ? 0.3 : 1;
const style = {
border: '1px solid var(--semi-color-border)',
marginBottom: 12,
backgroundColor: 'var(--semi-color-bg-2)',
cursor: 'move',
};
return connectDragSource(
connectDropTarget(
<div ref={node => (this.node = node)} style={{ style, opacity }}>
{component}
</div>
)
);
}
}
const cardSource = {
带分页器
你可以组合使用 Pagination, 实现一个分页的 List
xxxxxxxxxx
import { List, Pagination } from '@kousum/semi-ui-vue';
import { defineComponent, ref } from 'vue';
const Demo = defineComponent(() => {
const data = [
'围城',
'平凡的世界(全三册)',
'三体(全集)',
'雪中悍刀行(全集)',
'撒哈拉的故事',
'明朝那些事',
'一禅小和尚',
'沙丘',
'被讨厌的勇气',
'罪与罚',
'月亮与六便士',
'沉默的大多数',
];
const page = ref(1);
let pageSize = 4;
const getData = (page_) => {
let start = (page_ - 1) * pageSize;
let end = page_ * pageSize;
return data.slice(start, end);
};
带筛选器
你可以通过组装 Input 使用,实现对 List 列表的筛选
xxxxxxxxxx
import { List, Input } from '@kousum/semi-ui-vue';
import { IconSearch } from '@kousum/semi-icons-vue';
import { defineComponent, ref } from 'vue';
const Demo = defineComponent(() => {
const data = [
'围城',
'平凡的世界(全三册)',
'三体(全集)',
'雪中悍刀行(全集)',
'撒哈拉的故事',
'明朝那些事',
'一禅小和尚',
'沙丘',
'被讨厌的勇气',
'罪与罚',
];
const list = ref(data);
const onSearch = (string) => {
let newList;
if (string) {
newList = data.filter(item => item.includes(string));
} else {
newList = data;
}
list.value = (newList);
添加删除项
xxxxxxxxxx
import { List, Input, Button } from '@kousum/semi-ui-vue';
import { IconMinusCircle, IconPlusCircle } from '@kousum/semi-icons-vue';
import { defineComponent, ref } from 'vue';
const Demo = defineComponent(() => {
const data = [
'围城',
'平凡的世界(全三册)',
'三体(全集)',
'雪中悍刀行(全集)',
'撒哈拉的故事',
'明朝那些事',
'一禅小和尚',
'沙丘',
'被讨厌的勇气',
'罪与罚',
'月亮与六便士',
'沉默的大多数',
'第一人称单数',
];
const list = ref(data.slice(0, 8));
const updateList = (item) => {
let newList;
if (item) {
newList = list.value.filter(i => item !== i);
} else {
单选或多选
你可以通过组合使用 Radio 或 Checkbox 将 List 增强为一个列表选择器
xxxxxxxxxx
import { List, Input, Button, Checkbox, Radio, RadioGroup, CheckboxGroup } from '@kousum/semi-ui-vue';
import { defineComponent, ref } from 'vue';
const Demo = defineComponent(() => {
const data = [
'围城',
'平凡的世界(全三册)',
'三体(全集)',
'雪中悍刀行(全集)',
'撒哈拉的故事',
'明朝那些事',
'一禅小和尚',
'沙丘',
'被讨厌的勇气',
'罪与罚',
'月亮与六便士',
'沉默的大多数',
'第一人称单数',
];
const page = ref(1);
const checkboxVal = ref([data[0]]);
const radioVal = ref(data[0]);
let pageSize = 8;
const getData = (page) => {
响应键盘事件
你可以自行监听对应按键的键盘事件,实现不同 Item 的选择。如下面这个例子,可以使用上下方向键选择不同Item
xxxxxxxxxx
import { List, Input, Button } from '@kousum/semi-ui-vue';
import { defineComponent, onMounted, onUnmounted, ref } from 'vue';
const Demo = defineComponent(() => {
const data = [
'围城',
'平凡的世界(全三册)',
'三体(全集)',
'雪中悍刀行(全集)',
'撒哈拉的故事',
'明朝那些事',
'一禅小和尚',
'沙丘',
'被讨厌的勇气',
'罪与罚',
'月亮与六便士',
'沉默的大多数',
'第一人称单数',
];
const list = ref(data.slice(0, 10));
const hoverIndex = ref(-1);
const i = ref(-1);
let changeIndex = (offset) => {
let currentIndex = i.value;
let index = currentIndex + offset;
if (index < 0) {
以上书单例子的Demo中涉及到的自定义样式如下
.component-list-demo-booklist {
.list-item {
&:hover {
background-color: var(--semi-color-fill-0);
}
&:active {
background-color: var(--semi-color-fill-1);
}
}
}
body > .component-list-demo-drag-item {
font-size: 14px;
}
.component-list-demo-booklist-active-item {
background-color: var(--semi-color-fill-0);
}
API 参考
List
属性 | 说明 | 类型 | 默认值 |
---|---|---|---|
bordered | 是否显示边框 | boolean | false |
className | 自定义样式类名 | string | - |
dataSource | 列表数据源 | any[] | - |
emptyContent | 空列表的展示内容 | ReactNode | - |
footer | 列表底部 | ReactNode | - |
grid | 列表栅格配置 | Grid | - |
header | 列表头部 | ReactNode | - |
layout | 列表布局,支持vertical , horizontal | string | vertical |
loadMore | 加载更多的按钮 | ReactNode | - |
loading | 是否处于加载中,为true 时会显示 spin | boolean | false |
renderItem | 当使用 dataSource 时,可以用 renderItem 自定义渲染列表项 | (item, ind) => ReactNode | - |
size | 列表尺寸,支持 small , default , large | string | default |
split | 是否展示分割线 | boolean | true |
style | 自定义样式对象 | CSSProperties | - |
onClick | 点击回调事件 v>=1.0.0 | (e: event) => void | - |
onRightClick | 右键点击回调事件 v>=1.0.0 | (e: event) => void | - |
List grid props
v>=1.7.0 其他 grid 参数,请参考 Grid
属性 | 说明 | 类型 | 默认值 |
---|---|---|---|
span | 栅格占位格数 | number | - |
gutter | 栅格间隔 | number | 0 |
xs | <576px 响应式栅格,可为栅格数或一个包含其他属性的对象 | number|object | - |
sm | ≥576px 响应式栅格,可为栅格数或一个包含其他属性的对象 | number|object | - |
md | ≥768px 响应式栅格,可为栅格数或一个包含其他属性的对象 | number|object | - |
lg | ≥992px 响应式栅格,可为栅格数或一个包含其他属性的对象 | number|object | - |
xl | ≥1200px 响应式栅格,可为栅格数或一个包含其他属性的对象 | number|object | - |
xxl | ≥1600px 响应式栅格,可为栅格数或一个包含其他属性的对象 | number|object | - |
List.Item
属性 | 说明 | 类型 | 默认值 |
---|---|---|---|
align | 列表项头内容和主体内容的垂直对齐方式,支持 flex-start , flex-end , center , baseline , stretch | string | flex-start |
className | 自定义样式类名 | string | - |
extra | 列表项附加内容 | ReactNode | - |
header | 列表项头内容 | ReactNode | - |
main | 列表项主体内容 | ReactNode | - |
style | 自定义样式对象 | CSSProperties | - |
onClick | 点击回调事件 v>=1.0.0 | (e: event) => void | - |
onRightClick | 右键点击回调事件 v>=1.0.0 | (e: event) => void | - |
文案规范
- 首字母大写
- 结尾不跟随标点符号
- 语法平行:如主动态与被动态、陈述句与祈使句混合使用