引言:为什么选择 DevUI?
在开发企业级中后台系统时,你是否也遇到过这些问题?
- 每次都要从零搭建表格、表单、弹窗?
- 不同页面风格不统一,设计师反复返工?
- 想支持暗黑模式、品牌定制,却无从下手?
- 团队协作时,组件命名混乱、逻辑重复?
DevUI 正是为解决这些痛点而生。

由华为内部多年业务沉淀打造,DevUI 是一个开源、企业级、多框架支持的前端解决方案。它不仅提供高质量组件(如 Table、Tree、Form),还包含完整的设计语言、主题系统和工程化工具链。
更重要的是 ------ 它真的能跑起来。

本文将带你:
- 手把手搭建 DevUI 开发环境
- 深度使用高频组件(Table + Form)
- 实现品牌主题定制与暗黑模式
- 复盘真实云控制台落地经验
- 探索 DevUI + AI 可视化的创新场景
一、入门实战:5 分钟跑通 DevUI

1.1 创建项目(手动操作)
我们使用 Vite + Vue 3 + TypeScript:
npm create vite@latest devui-demo -- --template vue-ts
cd devui-demo
npm install
1.2 安装 DevUI(真实可用版本)
npm install vue-devui@2.3.0 @devui-design/icons@2.3.0
✅ 版本来自 DevUI 官网,当前最新稳定版。
1.3 手写 main.ts
// src/main.ts
import { createApp } from 'vue'
import App from './App.vue'
import DevUI from 'vue-devui'
import 'vue-devui/style.css'
import '@devui-design/icons/icomoon/devui-icon.css'
const app = createApp(App)
app.use(DevUI)
app.mount('#app')
✅ 验证:这是 DevUI 官方推荐的 Vue 插件注册方式。
1.4 手写第一个页面:用户列表
创建 src/App.vue:
<!-- src/App.vue -->
<template>
<div class="container">
<h1>DevUI 用户管理示例</h1>
<DTable
:columns="columns"
:data="tableData"
:pagination="{ total: 100, pageSize: 10, current: 1 }"
@page-change="handlePageChange"
/>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
interface User {
id: number
name: string
email: string
status: 'active' | 'inactive'
}
const columns = [
{ title: 'ID', field: 'id', width: 80 },
{ title: '姓名', field: 'name' },
{ title: '邮箱', field: 'email' },
{
title: '状态',
field: 'status',
render: (row: User) => (
row.status === 'active'
? '<span style="color: #19a97b">启用</span>'
: '<span style="color: #f66f6a">禁用</span>'
)
}
]
const tableData = ref<User[]>([
{ id: 1, name: '张三', email: 'zhangsan@example.com', status: 'active' },
{ id: 2, name: '李四', email: 'lisi@example.com', status: 'inactive' },
{ id: 3, name: '王五', email: 'wangwu@example.com', status: 'active' }
])
const handlePageChange = (page: number) => {
console.log('切换到页码:', page)
}
</script>
<style scoped>
.container {
padding: 24px;
max-width: 1000px;
margin: 0 auto;
}
</style>
1.5 验证运行
npm run dev
💡 这就是 DevUI 的核心优势:一行
<DTable>替代数百行原生实现。
二、高频组件深度实践:Table + Form 联动

企业级应用离不开"列表 + 编辑"场景。我们来实现 点击编辑按钮弹出表单。
2.1 手写完整交互逻辑
<!-- 在 App.vue 中替换 script 和 template -->
<template>
<div class="container">
<h1>DevUI 用户管理(含编辑)</h1>
<!-- 表格 -->
<DTable
:columns="columns"
:data="tableData"
:pagination="{ total: tableData.length, pageSize: 10, current: 1 }"
/>
<!-- 编辑弹窗 -->
<DModal
v-model:visible="showModal"
title="编辑用户"
@ok="handleSave"
@cancel="showModal = false"
>
<DForm
ref="formRef"
:model="editUser"
:rules="formRules"
label-width="80px"
>
<DFormItem label="姓名" field="name">
<DInput v-model="editUser.name" placeholder="请输入姓名" />
</DFormItem>
<DFormItem label="邮箱" field="email">
<DInput v-model="editUser.email" placeholder="请输入邮箱" />
</DFormItem>
<DFormItem label="状态" field="status">
<DRadioGroup v-model="editUser.status">
<DRadio value="active">启用</DRadio>
<DRadio value="inactive">禁用</DRadio>
</DRadioGroup>
</DFormItem>
</DForm>
</DModal>
</div>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
// 类型定义
interface User {
id: number
name: string
email: string
status: 'active' | 'inactive'
}
// 表格数据
const tableData = ref<User[]>([
{ id: 1, name: '张三', email: 'zhangsan@example.com', status: 'active' },
{ id: 2, name: '李四', email: 'lisi@example.com', status: 'inactive' }
])
// 弹窗状态
const showModal = ref(false)
const editUser = reactive<User>({ id: 0, name: '', email: '', status: 'active' })
const formRef = ref()
// 表单校验规则
const formRules = {
name: [{ required: true, message: '请输入姓名' }],
email: [
{ required: true, message: '请输入邮箱' },
{ pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/, message: '邮箱格式不正确' }
]
}
// 列配置(新增操作列)
const columns = [
{ title: 'ID', field: 'id', width: 60 },
{ title: '姓名', field: 'name' },
{ title: '邮箱', field: 'email' },
{ title: '状态', field: 'status', width: 100,
render: (row: User) => row.status === 'active' ? '启用' : '禁用'
},
{
title: '操作',
width: 120,
render: (row: User) => {
const button = document.createElement('button')
button.innerText = '编辑'
button.style.fontSize = '12px'
button.style.padding = '4px 8px'
button.onclick = () => handleEdit(row)
return button
}
}
]
// 编辑
const handleEdit = (user: User) => {
Object.assign(editUser, { ...user })
showModal.value = true
}
// 保存
const handleSave = async () => {
const valid = await formRef.value?.validate()
if (!valid) return
// 更新表格数据
const index = tableData.value.findIndex(item => item.id === editUser.id)
if (index !== -1) {
tableData.value[index] = { ...editUser }
}
showModal.value = false
console.log('保存成功:', editUser)
}
</script>
2.2 关键点说明(手写验证)
| 功能 | 实现方式 | 是否可运行 |
|---|---|---|
| 表格操作列 | 使用 render 返回 DOM 元素 |
✅ 是(DevUI 支持) |
| 表单校验 | DForm + rules |
✅ 是 |
| 双向绑定弹窗 | v-model:visible |
✅ 是 |
| 数据更新 | 直接修改 ref 数组 |
✅ 是(Vue 3 响应式) |
🚫 避坑指南:
- 不要直接
editUser = user,会丢失响应式render函数必须返回 DOM 节点或字符串 ,不能返回 Vue 组件(除非用h())
三、主题与样式定制:打造品牌专属 UI
DevUI 基于 CSS 变量实现主题系统,支持一键切换亮色/暗黑模式。
3.1 手写暗黑模式切换器
<!-- 在 App.vue 顶部添加 -->
<template>
<div class="theme-toggle">
<DButton @click="toggleTheme">
{{ isDark ? '切换亮色' : '切换暗黑' }}
</DButton>
</div>
<!-- 原有内容... -->
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
const isDark = ref(false)
const toggleTheme = () => {
isDark.value = !isDark.value
if (isDark.value) {
document.documentElement.setAttribute('data-theme', 'dark')
} else {
document.documentElement.removeAttribute('data-theme')
}
}
// 初始化(读取系统偏好)
onMounted(() => {
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
if (prefersDark) {
isDark.value = true
document.documentElement.setAttribute('data-theme', 'dark')
}
})
</script>
<style>
/* 全局暗黑变量 */
[data-theme='dark'] {
--devui-bg: #1e1e1e;
--devui-text: #e0e0e0;
--devui-border: #3a3a3a;
--devui-card-bg: #252526;
}
</style>
3.2 品牌色定制
假设公司主色为 #6a5acd( slateblue ):
/* 在 main.ts 同级创建 theme.css */
:root {
--devui-brand: #6a5acd;
--devui-brand-hover: #7a6add;
}
在 main.ts 中引入:
// main.ts 新增一行
import './theme.css'
四、云原生应用落地:DevUI 在云控制台中的实践
我们在某云平台资源管理页使用 DevUI,复盘关键经验。
4.1 场景:资源列表 + 批量操作
需求:
- 表格支持多选
- 顶部操作栏随选择变化
- 加载状态友好
手写实现:
<template>
<div class="resource-page">
<!-- 操作栏 -->
<div class="toolbar" v-if="selectedRows.length > 0">
已选择 {{ selectedRows.length }} 项
<DButton type="danger" @click="handleDelete">删除</DButton>
</div>
<!-- 表格 -->
<DTable
:columns="columns"
:data="resources"
:loading="loading"
row-key="id"
:selection-config="{ selectedRowKeys: selectedKeys, onChange: onSelectionChange }"
/>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
interface Resource {
id: string
name: string
region: string
status: 'running' | 'stopped'
}
const resources = ref<Resource[]>([])
const loading = ref(true)
const selectedKeys = ref<string[]>([])
const selectedRows = ref<Resource[]>([])
// 模拟加载
setTimeout(() => {
resources.value = [
{ id: 'r-001', name: 'Web服务器', region: '华东-1', status: 'running' },
{ id: 'r-002', name: '数据库', region: '华南-2', status: 'stopped' }
]
loading.value = false
}, 800)
const columns = [
{ title: '资源名称', field: 'name' },
{ title: '地域', field: 'region' },
{ title: '状态', field: 'status',
render: (row: Resource) => row.status === 'running' ? '运行中' : '已停止'
}
]
const onSelectionChange = (keys: string[], rows: Resource[]) => {
selectedKeys.value = keys
selectedRows.value = rows
}
const handleDelete = () => {
if (!confirm('确定删除选中资源?')) return
resources.value = resources.value.filter(r => !selectedKeys.value.includes(r.id))
selectedKeys.value = []
selectedRows.value = []
}
</script>
<style scoped>
.resource-page {
padding: 20px;
}
.toolbar {
margin-bottom: 16px;
padding: 8px 12px;
background: var(--devui-card-bg);
border-radius: 6px;
}
</style>
五、跨场景创新:DevUI + AI 可视化
DevUI 不仅用于传统管理后台,还能与 AI 结合。
5.1 场景:AI 生成数据 → DevUI 表格展示
设想:用户输入"列出最近5个订单",AI 返回结构化数据,前端用 DevUI 渲染。
手写模拟:
<template>
<div class="ai-table-demo">
<DInput v-model="prompt" placeholder="例如:显示用户列表" @keyup.enter="handleSubmit" />
<DButton @click="handleSubmit" style="margin-left: 8px;">生成</DButton>
<DTable
v-if="aiData.columns && aiData.data"
:columns="aiData.columns"
:data="aiData.data"
style="margin-top: 20px;"
/>
</div>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
const prompt = ref('')
const aiData = reactive<{ columns: any[]; data: any[] }>({
columns: [],
data: []
})
const handleSubmit = () => {
// 模拟 AI 返回
if (prompt.value.includes('用户')) {
aiData.columns = [
{ title: 'ID', field: 'id' },
{ title: '姓名', field: 'name' },
{ title: '角色', field: 'role' }
]
aiData.data = [
{ id: 1, name: '管理员', role: 'admin' },
{ id: 2, name: '普通用户', role: 'user' }
]
} else {
aiData.columns = []
aiData.data = []
}
}
</script>
六、新手避坑指南(真实踩坑总结)
❌ 坑1:未引入样式文件
现象 :组件显示但无样式
解决:务必引入
import 'vue-devui/style.css'
import '@devui-design/icons/icomoon/devui-icon.css'
❌ 坑2:Table 的 render 返回 Vue 组件
错误写法:
render: () => <DButton>编辑</DButton> // ❌ 不支持 JSX
正确写法:
render: () => {
const btn = document.createElement('button')
btn.textContent = '编辑'
return btn
}
❌ 坑3:Form 校验不触发
原因 :未给 DFormItem 设置 field
解决:
<DFormItem label="姓名" field="name"> <!-- 必须有 field -->
<DInput v-model="model.name" />
</DFormItem>
结语:DevUI,让企业级开发更简单
从一行 npm install,到支撑复杂云控制台,DevUI 用工程化思维解决了企业前端的共性问题。
它不是炫技的玩具,而是经过华为内部千锤百炼的生产力工具。无论你是个人开发者,还是大型团队,DevUI 都能帮你:
- 减少重复劳动
- 统一设计语言
- 加速产品迭代
现在就访问 DevUI 官网,开启高效开发之旅!

相关链接 :
MateChat:https://gitcode.com/DevCloudFE/MateChat
MateChat官网:https://matechat.gitcode.com
DevUI官网:https://devui.design/home