DevUI 是一套以「设计系统为灵魂、组件库为核心、工程化工具为支撑」的企业级前端解决方案,核心优势在于「企业级场景适配、全链路一致性设计、高可定制性与工程化效率协同」。

在当今快速迭代的互联网时代,企业级前端开发面临着效率、一致性、可维护性等多重挑战。作为华为内部多年业务沉淀的结晶,DevUI应运而生------这是一款基于Angular框架的开源前端解决方案,以"高效、开放、可信、乐趣"为设计价值观,致力于为企业中后台产品提供开箱即用的前端组件库。
DevUI 为 Web 应用提供了丰富的基础 UI 组件,我们还将持续探索企业级应用的最佳 UI 实践,欢迎尝试使用 DevUI。
高级列表
支持列表多选和批量删除功能,支持拖拽调整列宽,支持虚拟滚动和懒加载,支持过滤。

js
<da-layout-row [daGutter]="[24, 24]">
<da-col-item [daSpan]="24" [daXs]="24">
<div class="da-advance-form" dLoading [loading]="busy">
<div class="da-advace-form-content">
<d-data-table #dataTable [dataSource]="listData" [scrollable]="true" [tableWidthConfig]="tableWidthConfig">
<thead dTableHead>
<tr dTableRow>
<th dHeadCell>Id</th>
<th dHeadCell>Title</th>
<th dHeadCell>Priority</th>
<th dHeadCell>Iteration</th>
<th dHeadCell>Assignee</th>
<th dHeadCell>Status</th>
<th dHeadCell>Timeline</th>
<th dHeadCell>Actions</th>
</tr>
</thead>
<tbody dTableBody>
<ng-template let-rowItem="rowItem" let-rowIndex="rowIndex">
<tr dTableRow *ngIf="rowIndex === 0">
<td dTableCell [attr.colspan]="tableWidthConfig.length">
<div
*ngIf="!headerNewForm"
(click)="newRow()"
class="cursor-pointer"
>
<span class="tips-icon icon-add"></span>
<span style="margin-left: 10px">Create new data</span>
</div>
<div *ngIf="headerNewForm" class="edit-padding-fix">
<da-admin-form
[formConfig]="formConfig"
[formData]="defaultRowData"
class="editable-row"
(submitted)="quickRowAdded($event)"
(canceled)="quickRowCancel()"
></da-admin-form>
</div>
</td>
</tr>
<tr dTableRow>
<td
dTableCell
[editable]="true"
[editableTip]="editableTip"
[(editing)]="rowItem['idEdit']"
[rowItem]="rowItem"
[field]="'id'"
[beforeEditStart]="beforeEditStart"
[beforeEditEnd]="beforeEditEnd"
>
<span *ngIf="!rowItem['idEdit']">{{ rowItem?.id }}</span>
<div *ngIf="rowItem['idEdit']" class="edit-padding-fix">
<input
class="devui-form-control"
name="id"
[(ngModel)]="rowItem.id"
[attr.maxlength]="100"
[attr.minlength]="3"
/>
</div>
</td>
<td
dTableCell
[editable]="true"
[editableTip]="editableTip"
[(editing)]="rowItem['titleEdit']"
[rowItem]="rowItem"
[field]="'title'"
[beforeEditStart]="beforeEditStart"
[beforeEditEnd]="beforeEditEnd"
>
<span *ngIf="!rowItem['titleEdit']"
><d-tag [tag]="'Epic'" [labelStyle]="'epic'"></d-tag>
{{ rowItem?.title }}</span
>
<div *ngIf="rowItem['titleEdit']" class="edit-padding-fix">
<input
class="devui-form-control"
name="title"
[(ngModel)]="rowItem.title"
[attr.maxlength]="100"
[attr.minlength]="3"
/>
</div>
</td>
<td
dTableCell
[editable]="true"
[editableTip]="editableTip"
[(editing)]="rowItem['priorityEdit']"
[rowItem]="rowItem"
[field]="'priority'"
[beforeEditStart]="beforeEditStart"
[beforeEditEnd]="beforeEditEnd"
>
<span *ngIf="!rowItem['priorityEdit']"
><d-tag
[tag]="rowItem?.priority"
[labelStyle]="rowItem?.priority"
></d-tag
></span>
<div
*ngIf="rowItem['priorityEdit']"
class="edit-padding-fix"
>
<d-select
name="priority"
[(ngModel)]="rowItem.priority"
[options]="priorities"
></d-select>
</div>
</td>
<td
dTableCell
[editable]="true"
[editableTip]="editableTip"
[(editing)]="rowItem['iterationEdit']"
[rowItem]="rowItem"
[field]="'iteration'"
[beforeEditStart]="beforeEditStart"
[beforeEditEnd]="beforeEditEnd"
>
<span *ngIf="!rowItem['iterationEdit']">{{
rowItem?.iteration
}}</span>
<div
*ngIf="rowItem['iterationEdit']"
class="edit-padding-fix"
>
<input
dTextInput
size="sm"
[(ngModel)]="rowItem.iteration"
/>
</div>
</td>
<td
dTableCell
[editable]="true"
[editableTip]="editableTip"
[(editing)]="rowItem['assigneeEdit']"
[rowItem]="rowItem"
[field]="'assignee'"
[beforeEditStart]="beforeEditStart"
[beforeEditEnd]="beforeEditEnd"
>
<span *ngIf="!rowItem['assigneeEdit']">
<d-avatar
[name]="rowItem.assignee"
[width]="24"
[height]="24"
></d-avatar>
<span style="margin-left: 6px">{{
rowItem.assignee
}}</span>
</span>
<div
*ngIf="rowItem['assigneeEdit']"
class="edit-padding-fix"
>
<input
dTextInput
size="sm"
[(ngModel)]="rowItem.assignee"
/>
</div>
</td>
<td
dTableCell
[editable]="true"
[editableTip]="editableTip"
[(editing)]="rowItem['statusEdit']"
[rowItem]="rowItem"
[field]="'status'"
[beforeEditStart]="beforeEditStart"
[beforeEditEnd]="beforeEditEnd"
>
<span *ngIf="!rowItem['statusEdit']"
><span [ngClass]="rowItem?.status.split(' ')[0]">{{
rowItem?.status || "--"
}}</span></span
>
<div *ngIf="rowItem['statusEdit']" class="edit-padding-fix">
<d-select
name="status"
[(ngModel)]="rowItem.status"
[options]="['Stuck', 'Done', 'Working on it']"
></d-select>
</div>
</td>
<td
dTableCell
[editable]="true"
[(editing)]="rowItem['dateEdit']"
>
<span *ngIf="!rowItem['dateEdit']">{{
rowItem?.timeline | i18nDate: "short":false
}}</span>
<form
*ngIf="rowItem['dateEdit']"
class="form-inline edit-padding-fix"
>
<div class="devui-form-group">
<div class="devui-input-group devui-dropdown-origin">
<input
class="devui-form-control search"
name="date"
[(ngModel)]="rowItem.timeline"
dDatepicker
appendToBody
#datePicker="datepicker"
[autoOpen]="true"
(ngModelChange)="onEditEnd(rowItem, 'dateEdit')"
/>
<div
class="devui-input-group-addon"
(click)="datePicker.toggle()"
>
<i class="icon icon-calendar"></i>
</div>
</div>
</div>
</form>
</td>
<td>
<d-button
icon="icon-delete"
bsStyle="text-dark"
title="delete"
(click)="deleteRow(rowIndex)"
></d-button>
</td>
</tr>
</ng-template>
</tbody>
</d-data-table>
</div>
<d-pagination
[size]="'sm'"
[total]="pager.total"
[(pageSize)]="pager.pageSize"
[(pageIndex)]="pager.pageIndex"
[canViewTotal]="true"
[canChangePageSize]="true"
[canJumpPage]="true"
[maxItems]="5"
(pageIndexChange)="onPageChange($event)"
(pageSizeChange)="onSizeChange($event)"
>
</d-pagination>
</div>
</da-col-item>
</da-layout-row>
这段代码是一个基于Angular框架的前端组件模板,主要用于展示和管理一个可编辑的数据表格。下面是对代码各部分的详细解释:
1. 布局结构:
- 使用和进行响应式布局,[daGutter]设置列间距。
- dLoading指令配合[loading]="busy"实现加载状态显示。
2. 数据表格 (d-data-table):
- dataSource绑定表格数据listData
- tableWidthConfig配置列宽
- 表头定义了8列:Id, Title, Priority, Iteration, Assignee, Status, Timeline, Actions
3. 新增行功能:
- 第一行是特殊的新建数据行
- headerNewForm控制显示"新建"按钮还是表单
- 点击"Create new data"触发newRow()方法
- 表单通过da-admin-form组件渲染,支持提交(submitted)和取消(canceled)事件
4. 单元格编辑功能:
- 每个单元格都配置了编辑能力:
-
editable\]="true"启用编辑
- *ngIf="!rowItem['fieldEdit']"控制显示静态文本
- *ngIf="rowItem['fieldEdit']"控制显示编辑输入控件
-
- 不同字段使用不同的编辑控件:
- 文本字段:输入框
- 优先级:下拉选择器
- 标题:带标签样式显示
5. 关键特性:
- 编辑前后的钩子函数:beforeEditStart, beforeEditEnd
- 字段验证:maxlength, minlength属性
- 标签组件:用于高亮显示优先级和类型
- 响应式设计:[daXs]适配小屏幕设备
整体而言,这是一个功能完整的可编辑数据表格界面,集成了数据展示、新增、编辑、验证等多种功能。
js
import { Component, OnInit } from '@angular/core';
import { DialogService, EditableTip, TableWidthConfig } from 'ng-devui';
import { Subscription } from 'rxjs';
import { ListDataService } from './list-data.service';
import { FormLayout } from 'ng-devui';
import { FormConfig } from 'src/app/@shared/components/admin-form/admin-form.type';
@Component({
selector: 'da-advance-form',
templateUrl: './advance-form.component.html',
styleUrls: ['./advance-form.component.scss'],
})
export class AdvanceFormComponent implements OnInit {
editableTip = EditableTip.btn;
nameEditing: boolean;
busy: Subscription;
pager = {
total: 0,
pageIndex: 1,
pageSize: 10,
};
listData = [];
headerNewForm = false;
formConfig: FormConfig = {
layout: FormLayout.Horizontal,
labelSize: 'sm',
items: [
{
label: 'Id',
prop: 'id',
type: 'input',
},
{
label: 'Title',
prop: 'title',
type: 'input',
required: true,
rule: {
validators: [{ required: true }],
},
},
{
label: 'Priority',
prop: 'priority',
type: 'select',
options: ['Low', 'Medium', 'High'],
required: true,
rule: {
validators: [{ required: true }],
},
},
{
label: 'Iteration',
prop: 'iteration',
type: 'input',
},
{
label: 'Assignee',
prop: 'assignee',
type: 'input',
required: true,
rule: {
validators: [{ required: true }],
},
},
{
label: 'Status',
prop: 'status',
type: 'select',
options: ['Stuck', 'Done', 'Working on it'],
},
{
label: 'Timeline',
prop: 'timeline',
type: 'datePicker',
},
],
};
defaultRowData = {
id: '',
title: '',
priority: 'Low',
iteration: '',
assignee: '',
status: 'Stuck',
timeline: new Date(),
};
priorities = ['Low', 'Medium', 'High'];
tableWidthConfig: TableWidthConfig[] = [
{
field: 'id',
width: '150px',
},
{
field: 'title',
width: '200px',
},
{
field: 'priority',
width: '100px',
},
{
field: 'iteration',
width: '100px',
},
{
field: 'assignee',
width: '100px',
},
{
field: 'status',
width: '100px',
},
{
field: 'timeline',
width: '100px',
},
{
field: 'Actions',
width: '100px',
},
];
constructor(private listDataService: ListDataService, private dialogService: DialogService) {}
ngOnInit() {
this.getList();
}
onEditEnd(rowItem, field) {
rowItem[field] = false;
}
getList() {
this.busy = this.listDataService.getListData(this.pager).subscribe((res) => {
res.pageList.$expandConfig = { expand: false };
this.listData = res.pageList;
this.pager.total = res.total;
});
}
beforeEditStart = (rowItem, field) => {
return true;
};
beforeEditEnd = (rowItem, field) => {
console.log('beforeEditEnd');
if (rowItem && rowItem[field].length < 3) {
return false;
} else {
return true;
}
};
newRow() {
this.headerNewForm = true;
}
getuuid() {
return new Date().getTime() + 'CNWO';
}
quickRowAdded(e) {
const newData = { ...e };
this.listData.unshift(newData);
this.headerNewForm = false;
}
quickRowCancel() {
this.headerNewForm = false;
}
subRowAdded(index, item) {
this.listData[index].$expandConfig.expand = false;
const newData = { ...this.defaultRowData };
this.listData.splice(index + 1, 0, newData);
}
subRowCancel(index) {
this.listData[index].$expandConfig.expand = false;
}
toggleExpand(rowItem) {
if (rowItem.$expandConfig) {
rowItem.$expandConfig.expand = !rowItem.$expandConfig.expand;
}
}
onPageChange(e) {
this.pager.pageIndex = e;
this.getList();
}
onSizeChange(e) {
this.pager.pageSize = e;
this.getList();
}
deleteRow(index) {
const results = this.dialogService.open({
id: 'delete-dialog',
width: '346px',
maxHeight: '600px',
title: 'Delete',
showAnimate: false,
content: 'Are you sure you want to delete it?',
backdropCloseable: true,
onClose: () => {},
buttons: [
{
cssClass: 'primary',
text: 'Ok',
disabled: false,
handler: () => {
this.listData.splice(index, 1);
results.modalInstance.hide();
},
},
{
id: 'btn-cancel',
cssClass: 'common',
text: 'Cancel',
handler: () => {
results.modalInstance.hide();
},
},
],
});
}
}
这段代码是一个基于 Angular 框架的 TypeScript 组件,名为 AdvanceFormComponent,用于实现一个具备数据展示、编辑、新增和删除功能的高级表单页面。它结合了 ng-devui UI 库提供的组件来构建一个可交互的数据表格界面。
主要功能解析:
1. 组件初始化与数据获取
- 实现了 OnInit 接口,在组件初始化时调用 getList() 方法从服务 (ListDataService) 获取初始数据并填充到页面表格中。
- 使用 pager 对象管理分页信息(如当前页码、每页条数等)。
2. 表单配置
- 定义了一个 formConfig 对象,描述了表单字段的信息(如标签、类型、校验规则)。包括:
- 输入框(Input):如 Id、Title、Iteration、Assignee。
- 下拉选择器(Select):如 Priority、Status。
- 日期选择器(DatePicker):Timeline 字段。
- 设置默认表单数据 defaultRowData,用于新行创建时的初始值。
3. 表格列宽配置
- 使用 tableWidthConfig 数组定义每一列的宽度,确保表格布局整齐美观。
4. 编辑功能
- 利用 editableTip 配置单元格编辑方式为按钮触发。
- 提供两个钩子函数 beforeEditStart 和 beforeEditEnd 控制编辑开始和结束的行为(例如限制最小长度)。
- 单元格点击后进入编辑状态,并可通过保存或取消退出编辑模式。
5. 新增行功能
- 点击 "Create new data" 触发 newRow() 显示顶部新增表单。
- 表单提交后调用 quickRowAdded() 将新数据插入列表头部。
- 取消操作则通过 quickRowCancel() 隐藏表单。
6. 展开子行功能
- 支持点击某一行展开其子项(可能用于更详细的编辑或查看)。
- 子行新增和取消分别由 subRowAdded() 和 subRowCancel() 处理。
7. 分页与刷新
页面大小改变和翻页动作会重新调用 getList() 更新数据列表。
8. 删除确认弹窗
删除操作通过 dialogService.open() 打开模态对话框让用户确认是否执行删除。
js
import { NgModule } from '@angular/core';
import { AdvanceFormComponent } from './advance-form.component';
import {
SelectModule,
DataTableModule,
LoadingModule,
PaginationModule,
TagsModule,
DatepickerModule
} from 'ng-devui';
import { SharedModule } from 'src/app/@shared/shared.module';
import { ListDataService } from './list-data.service';
import { AdminFormModule } from 'src/app/@shared/components/admin-form';
@NgModule({
declarations: [AdvanceFormComponent],
imports: [
SharedModule,
DataTableModule,
LoadingModule,
SelectModule,
TagsModule,
PaginationModule,
AdminFormModule,
DatepickerModule
],
exports: [AdvanceFormComponent],
providers: [ListDataService],
})
export class AdvanceFormModule {}
这段代码是 Angular 框架中的一个 NgModule(模块)定义,名为 AdvanceFormModule。它的主要作用是组织和封装与"高级表单"相关的组件、服务和依赖项,以便在应用中复用。
具体功能解析如下:
-
- 模块声明:通过 @NgModule 装饰器定义了一个名为 AdvanceFormModule 的 Angular 模块
-
- 组件注册:将 AdvanceFormComponent 组件声明在该模块中,使其可在模块内使用
-
- 依赖导入:导入了多个 ng-devui UI 组件库模块,如数据表格、下拉选择、标签、分页、加载指示器和日期选择器等
-
- 共享模块:引入了应用级别的 SharedModule,可复用通用组件和指令
服务提供:在 providers 中注册了 ListDataService 服务,用于数据获取和管理
- 共享模块:引入了应用级别的 SharedModule,可复用通用组件和指令
-
- 模块导出:将 AdvanceFormComponent 导出,使其他模块可以使用该组件
js
import { Injectable } from '@angular/core';
import { Observable, of as observableOf } from 'rxjs';
import { delay } from 'rxjs/operators';
export interface Item {
id?: string;
title?: string;
priority?: string;
iteration?: string;
assignee?: string;
status?: string;
timeline?: string;
$checked?: boolean;
$expandConfig?: any;
children?: any;
chosen?: boolean;
$isChildTableOpen?: boolean;
}
export interface ListPager {
pageSize?: number;
pageIndex?: number
}
export interface CardAction {
icon?: string;
num?: string;
}
export interface Card {
name?: string;
id?: number;
ame?: string;
title?: string;
imgSrc?: string;
subTitle?: string;
content?: string;
agreeNum?: number;
starsNum?: number;
messageNum?: number;
actions?: CardAction[];
}
@Injectable()
export class ListDataService {
private basicData: Item[] = [
{
id: '230000200706283786',
title: 'Yriqtjdjd Omvqxe Xxlfgjtnj Hsyf Qecu',
priority: 'Medium',
iteration: 'iteration',
assignee: 'Shirley Martin',
status: 'Stuck',
timeline: '1985-01-10',
children: [
{
id: '230000197101025982',
title: 'Volbp Wdobo Ukme Szbgjmeo Kobn Aawyirm Rmbobdyn',
priority: 'Low',
iteration: 'iteration',
assignee: 'Daniel Martinez',
status: 'Done',
timeline: '2008-08-02',
},
{
id: '230000197101025982',
title: 'Volbp Wdobo Ukme Szbgjmeo Kobn Aawyirm Rmbobdyn',
priority: 'Low',
iteration: 'iteration',
assignee: 'Daniel Martinez',
status: 'Done',
timeline: '2008-08-02',
children: [
{
id: '22000019860224174X',
title: 'Ozhtyax Wfpp Essvpkjrx Havonov Cdcmgmggnj Vqwcwd Ooolirn',
priority: 'High',
iteration: 'iteration',
assignee: 'Margaret Clark',
status: '',
timeline: '2015-05-08',
},
{
id: '140000197907226183',
title: 'Govfunhwa Gkvcrv Uvbq Gqyrwntx Ofnnuwrnh',
priority: 'Low',
iteration: 'iteration',
assignee: 'Jason Rodriguez',
status: 'Done',
timeline: '1994-02-08',
},
{
id: '440000201807134089',
title: 'Rbh Wklmth Xkeg Iuzan Isufy',
priority: 'Medium',
iteration: 'iteration',
assignee: 'Kenneth Robinson',
status: 'Done',
timeline: '2017-02-04',
},
],
},
{
id: '520000200110166246',
title: 'Rrqcneg Iknm Tbo',
priority: 'Medium',
iteration: 'iteration',
assignee: 'Paul Hernandez',
status: 'Stuck',
timeline: '2017-02-01',
},
],
},
{
id: '710000197203093702',
title: 'Hwgx Vkdg Kfap Tke Miyxg Hyelo',
priority: 'Low',
iteration: 'iteration',
assignee: 'Michael Walker',
status: 'Stuck',
timeline: '2018-08-04',
},
{
id: '230000197101025982',
title: 'Volbp Wdobo Ukme Szbgjmeo Kobn Aawyirm Rmbobdyn',
priority: 'Low',
iteration: 'iteration',
assignee: 'Daniel Martinez',
status: 'Done',
timeline: '2008-08-02',
},
{
id: '520000200110166246',
title: 'Rrqcneg Iknm Tbo',
priority: 'Medium',
iteration: 'iteration',
assignee: 'Paul Hernandez',
status: 'Stuck',
timeline: '2017-02-01',
},
{
id: '22000019860224174X',
title: 'Ozhtyax Wfpp Essvpkjrx Havonov Cdcmgmggnj Vqwcwd Ooolirn',
priority: 'High',
iteration: 'iteration',
assignee: 'Margaret Clark',
status: '',
timeline: '2015-05-08',
},
{
id: '140000197907226183',
title: 'Govfunhwa Gkvcrv Uvbq Gqyrwntx Ofnnuwrnh',
priority: 'Low',
iteration: 'iteration',
assignee: 'Jason Rodriguez',
status: 'Done',
timeline: '1994-02-08',
},
{
id: '440000201807134089',
title: 'Rbh Wklmth Xkeg Iuzan Isufy',
priority: 'Medium',
iteration: 'iteration',
assignee: 'Kenneth Robinson',
status: 'Done',
timeline: '2017-02-04',
},
{
id: '430000197502028524',
title: 'Zcbap Qqoyxrimw Hndekkk',
priority: 'Medium',
iteration: 'iteration',
assignee: 'Jason Garcia',
status: 'Done',
timeline: '2009-09-09',
},
{
id: '360000199102159374',
title: 'Sarbgroo Rpru Krzhklgihv Vfgha Bunyqz',
priority: 'Medium',
iteration: 'iteration',
assignee: 'Michelle Lee',
status: 'Done',
timeline: '2019-02-22',
},
{
id: '530000200702210206',
title: 'Tksno Nvsche Rmysrkwsy Qxjvulnsd Rzo',
priority: 'Medium',
iteration: 'iteration',
assignee: 'Ruth Anderson',
status: 'Done',
timeline: '1980-01-05',
},
{
id: '120000201207262146',
title: 'Mcpnwxqws Dfqrmphi Ipl',
priority: 'Medium',
iteration: 'iteration',
assignee: 'Susan Garcia',
status: 'Done',
timeline: '1972-01-14',
},
{
id: '360000199409270026',
title: 'Lwomkvcng Hwwj Hhjxlz',
priority: 'High',
iteration: 'iteration',
assignee: 'Kevin Johnson',
status: 'Done',
timeline: '1991-06-03',
},
{
id: '500000201603203501',
title: 'Mjfflwan Oebhykk Ppjpy Itnxlw Jqtm Lcsloswa',
priority: 'Low',
iteration: 'iteration',
assignee: 'Jennifer Harris',
status: 'Stuck',
timeline: '2014-08-09',
},
{
id: '130000197712017750',
title: 'Sdudlc Hcrfkaz Kufynndl Oprvfsh Teipjsd',
priority: 'High',
iteration: 'iteration',
assignee: 'Kimberly Harris',
status: 'Stuck',
timeline: '1990-12-12',
},
{
id: '510000201304014163',
title: 'Blhh Pdisxhqkl Ixnj Erbpeel Bjuvr Cdngo',
priority: 'High',
iteration: 'iteration',
assignee: 'Angela Martinez',
status: '',
timeline: '2005-04-01',
},
{
id: '820000199503017685',
title: 'Bjzruarho Yqwrkksnkb Gsjr Otwbvihju',
priority: 'Medium',
iteration: 'iteration',
assignee: 'Ronald Hernandez',
status: 'Working on it',
timeline: '2016-07-01',
},
{
id: '820000198503197802',
title: 'Zjc Jwtut Mftvcu Ctylolht Xcdi',
priority: 'Low',
iteration: 'iteration',
assignee: 'Edward Wilson',
status: 'Stuck',
timeline: '1989-03-29',
},
{
id: '820000201707240870',
title: 'Cbksh Iswxgkytcw Pmbzpv Hphtfnxw',
priority: 'High',
iteration: 'iteration',
assignee: 'Betty Lewis',
status: 'Done',
timeline: '1987-09-21',
},
{
id: '460000197810188840',
title: 'Vmjjt Qpqjcb Ffwmwnxdn Tften Yidwthci',
priority: 'Low',
iteration: 'iteration',
assignee: 'Angela Jones',
status: 'Done',
timeline: '2003-03-20',
},
{
id: '130000198908073513',
title: 'Avkacxzqab Bfxtwexs Buwwvxe',
priority: 'High',
iteration: 'iteration',
assignee: 'Anthony Jones',
status: 'Stuck',
timeline: '2003-02-22',
},
];
private cardSource: Card[] = [
{
name: 'Angular',
title: 'Angular',
content:
'DevUI 是面向企业中后台产品的开源前端解决方案,其设计价值观基于"至简"、"沉浸"、"灵活"三种自然与人文相结合的理念,旨在为设计....',
actions: [
{
icon: 'icon-star-o',
num: '617',
},
{
icon: 'icon-fork',
num: '100',
},
],
},
{
name: 'DevUI',
title: 'DevUI',
content:
'DevUI 是面向企业中后台产品的开源前端解决方案,其设计价值观基于"至简"、"沉浸"、"灵活"三种自然与人文相结合的理念,旨在为设计...',
actions: [
{
icon: 'icon-star-o',
num: '617',
},
{
icon: 'icon-fork',
num: '100',
},
],
},
{
name: 'BootStrap',
title: 'BootStrap',
content:
'DevUI 是面向企业中后台产品的开源前端解决方案,其设计价值观基于"至简"、"沉浸"、"灵活"三种自然与人文相结合的理念,旨在为设计....',
actions: [
{
icon: 'icon-star-o',
num: '617',
},
{
icon: 'icon-fork',
num: '100',
},
],
},
{
name: 'React',
title: 'React',
imgSrc:
'https://codingthesmartway.com/wp-content/uploads/2019/12/logo_react.png',
content:
'DevUI 是面向企业中后台产品的开源前端解决方案,其设计价值观基于"至简"、"沉浸"、"灵活"三种自然与人文相结合的理念,旨在为设计....',
actions: [
{
icon: 'icon-star-o',
num: '617',
},
{
icon: 'icon-fork',
num: '100',
},
],
},
{
name: 'Vue',
title: 'Vue',
imgSrc: 'https://vuejs.org/images/logo.png',
content:
'DevUI 是面向企业中后台产品的开源前端解决方案,其设计价值观基于"至简"、"沉浸"、"灵活"三种自然与人文相结合的理念,旨在为设计....',
actions: [
{
icon: 'icon-star-o',
num: '617',
},
{
icon: 'icon-fork',
num: '100',
},
],
},
{
name: 'Webpack',
title: 'Webpack',
imgSrc:
'https://webpack.js.org/icon-square-small.85ba630cf0c5f29ae3e3.svg',
content:
'DevUI 是面向企业中后台产品的开源前端解决方案,其设计价值观基于"至简"、"沉浸"、"灵活"三种自然与人文相结合的理念,旨在为设计....',
actions: [
{
icon: 'icon-star-o',
num: '617',
},
{
icon: 'icon-fork',
num: '100',
},
],
},
{
name: 'DevUI',
title: 'DevUI',
content:
'DevUI是面向企业中后台产品的开源前端解决方案,其设计价值观基于"至简"、"沉浸"、"灵活"三种自然与人文相结合的理念,旨在为设计...',
actions: [
{
icon: 'icon-star-o',
num: '617',
},
{
icon: 'icon-fork',
num: '100',
},
],
},
{
name: 'BootStrap',
title: 'BootStrap',
content:
'DevUI 是面向企业中后台产品的开源前端解决方案,其设计价值观基于"至简"、"沉浸"、"灵活"三种自然与人文相结合的理念,旨在为设计....',
actions: [
{
icon: 'icon-star-o',
num: '617',
},
{
icon: 'icon-fork',
num: '100',
},
],
},
{
name: 'React',
title: 'React',
imgSrc:
'https://codingthesmartway.com/wp-content/uploads/2019/12/logo_react.png',
content:
'DevUI 是面向企业中后台产品的开源前端解决方案,其设计价值观基于"至简"、"沉浸"、"灵活"三种自然与人文相结合的理念,旨在为设计....',
actions: [
{
icon: 'icon-star-o',
num: '617',
},
{
icon: 'icon-fork',
num: '100',
},
],
},
{
name: 'Vue',
title: 'Vue',
imgSrc: 'https://vuejs.org/images/logo.png',
content:
'DevUI 是面向企业中后台产品的开源前端解决方案,其设计价值观基于"至简"、"沉浸"、"灵活"三种自然与人文相结合的理念,旨在为设计....',
actions: [
{
icon: 'icon-star-o',
num: '617',
},
{
icon: 'icon-fork',
num: '100',
},
],
},
{
name: 'Webpack',
title: 'Webpack',
imgSrc:
'https://webpack.js.org/icon-square-small.85ba630cf0c5f29ae3e3.svg',
content:
'DevUI 是面向企业中后台产品的开源前端解决方案,其设计价值观基于"至简"、"沉浸"、"灵活"三种自然与人文相结合的理念,旨在为设计....',
actions: [
{
icon: 'icon-star-o',
num: '617',
},
{
icon: 'icon-fork',
num: '100',
},
],
},
{
name: 'DevUI',
title: 'DevUI',
content:
'DevUI是面向企业中后台产品的开源前端解决方案,其设计价值观基于"至简"、"沉浸"、"灵活"三种自然与人文相结合的理念,旨在为设计...',
actions: [
{
icon: 'icon-star-o',
num: '617',
},
{
icon: 'icon-fork',
num: '100',
},
],
},
{
name: 'BootStrap',
title: 'BootStrap',
content:
'DevUI 是面向企业中后台产品的开源前端解决方案,其设计价值观基于"至简"、"沉浸"、"灵活"三种自然与人文相结合的理念,旨在为设计....',
actions: [
{
icon: 'icon-star-o',
num: '617',
},
{
icon: 'icon-fork',
num: '100',
},
],
},
{
name: 'React',
title: 'React',
imgSrc:
'https://codingthesmartway.com/wp-content/uploads/2019/12/logo_react.png',
content:
'DevUI 是面向企业中后台产品的开源前端解决方案,其设计价值观基于"至简"、"沉浸"、"灵活"三种自然与人文相结合的理念,旨在为设计....',
actions: [
{
icon: 'icon-star-o',
num: '617',
},
{
icon: 'icon-fork',
num: '100',
},
],
},
{
name: 'Vue',
title: 'Vue',
imgSrc: 'https://vuejs.org/images/logo.png',
content:
'DevUI 是面向企业中后台产品的开源前端解决方案,其设计价值观基于"至简"、"沉浸"、"灵活"三种自然与人文相结合的理念,旨在为设计....',
actions: [
{
icon: 'icon-star-o',
num: '617',
},
{
icon: 'icon-fork',
num: '100',
},
],
},
{
name: 'Webpack',
title: 'Webpack',
imgSrc:
'https://webpack.js.org/icon-square-small.85ba630cf0c5f29ae3e3.svg',
content:
'DevUI 是面向企业中后台产品的开源前端解决方案,其设计价值观基于"至简"、"沉浸"、"灵活"三种自然与人文相结合的理念,旨在为设计....',
actions: [
{
icon: 'icon-star-o',
num: '617',
},
{
icon: 'icon-fork',
num: '100',
},
],
},
];
private pagerList(data, pager) {
return data.slice(
pager.pageSize * (pager.pageIndex - 1),
pager.pageSize * pager.pageIndex
);
}
getListData(pager: ListPager): Observable<any> {
return observableOf({
pageList: this.pagerList(this.basicData, pager),
total: this.basicData.length,
}).pipe(delay(1000));
}
}
这段代码是一个 Angular 服务(Service),名为 ListDataService,主要功能是为应用程序提供数据。具体分析如下:
1. 核心作用:
- 使用 @Injectable() 装饰器标记为可注入服务
- 模拟后端数据接口,提供表格/列表数据的获取功能
2. 数据结构定义:
- Item 接口:定义了列表项的数据结构,包括 id、标题、优先级、迭代、负责人、状态、时间线等字段
- 支持树形结构数据(通过 children 字段嵌套子项)
- ListPager 接口:定义分页参数(页大小、页码)
- Card 和 CardAction 接口:定义卡片数据结构(可能是另一种视图模式)
3. 数据处理:
- basicData:预置的静态模拟数据数组
- 使用 RxJS 的 Observable 和 delay 操作符模拟异步数据获取
- 提供 getTreeTableData 方法返回分页后的数据
- 支持通过 pager 参数控制数据分页
4. 技术特点:
- 采用响应式编程(RxJS)处理异步数据流
- 数据模拟:使用 delay 模拟网络请求延迟
- 类型安全:通过 TypeScript 接口严格定义数据结构
- 可扩展性:支持树形表格和普通列表两种数据格式
这是一个典型的数据服务层实现,用于前端开发中的数据模拟和状态管理。
DevUI是华为开源的企业级前端解决方案,基于Angular框架,提供丰富的基础UI组件和高效开发工具。其核心优势包括企业级场景适配、全链路一致性设计和高可定制性。示例展示了高级列表组件功能,支持多选、批量删除、拖拽列宽、虚拟滚动等特性,并提供了可编辑单元格、快速添加行等交互功能,满足复杂业务场景需求。通过代码示例可见,DevUI组件库能够显著提升中后台系统的开发效率,同时保持UI设计的一致性。
MateChat:https://gitcode.com/DevCloudFE/MateChat
MateChat官网:https://matechat.gitcode.com
DevUI官网:https://devui.design/home