前端组件库指南
目录
UI 组件库
Element Plus
javascript
// 安装
npm install element-plus
// 引入
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
// 使用
<template>
<el-button type="primary">按钮</el-button>
<el-input v-model="input" placeholder="请输入内容"></el-input>
<el-table :data="tableData">
<el-table-column prop="date" label="日期"></el-table-column>
<el-table-column prop="name" label="姓名"></el-table-column>
</el-table>
</template>
<script setup>
import { ref } from 'vue'
const input = ref('')
const tableData = ref([
{ date: '2024-01-01', name: '张三' },
{ date: '2024-01-02', name: '李四' }
])
</script>说明:
- 组件丰富
- 文档完善
- 主题定制
- 国际化支持
Ant Design Vue
javascript
// 安装
npm install ant-design-vue
// 引入
import Antd from 'ant-design-vue'
import 'ant-design-vue/dist/antd.css'
// 使用
<template>
<a-button type="primary">按钮</a-button>
<a-input v-model:value="input" placeholder="请输入内容"></a-input>
<a-table :dataSource="tableData" :columns="columns"></a-table>
</template>
<script setup>
import { ref } from 'vue'
const input = ref('')
const tableData = ref([
{ key: '1', date: '2024-01-01', name: '张三' },
{ key: '2', date: '2024-01-02', name: '李四' }
])
const columns = [
{ title: '日期', dataIndex: 'date' },
{ title: '姓名', dataIndex: 'name' }
]
</script>说明:
- 企业级组件
- 设计规范
- 主题定制
- 国际化支持
Vuetify
javascript
// 安装
npm install vuetify
// 引入
import Vuetify from 'vuetify'
import 'vuetify/styles'
// 使用
<template>
<v-btn color="primary">按钮</v-btn>
<v-text-field v-model="input" label="输入框"></v-text-field>
<v-data-table :headers="headers" :items="items"></v-data-table>
</template>
<script setup>
import { ref } from 'vue'
const input = ref('')
const headers = [
{ title: '日期', key: 'date' },
{ title: '姓名', key: 'name' }
]
const items = ref([
{ date: '2024-01-01', name: '张三' },
{ date: '2024-01-02', name: '李四' }
])
</script>说明:
- Material Design
- 响应式设计
- 主题定制
- 动画效果
移动端组件库
Vant
javascript
// 安装
npm install vant
// 引入
import Vant from 'vant'
import 'vant/lib/index.css'
// 使用
<template>
<van-button type="primary">按钮</van-button>
<van-field v-model="input" label="输入框"></van-field>
<van-cell-group>
<van-cell v-for="item in list" :key="item.id" :title="item.title"></van-cell>
</van-cell-group>
</template>
<script setup>
import { ref } from 'vue'
const input = ref('')
const list = ref([
{ id: 1, title: '列表项 1' },
{ id: 2, title: '列表项 2' }
])
</script>说明:
- 轻量级
- 性能优化
- 主题定制
- 按需引入
NutUI
javascript
// 安装
npm install @nutui/nutui
// 引入
import NutUI from '@nutui/nutui'
import '@nutui/nutui/dist/style.css'
// 使用
<template>
<nut-button type="primary">按钮</nut-button>
<nut-input v-model="input" label="输入框"></nut-input>
<nut-cell-group>
<nut-cell v-for="item in list" :key="item.id" :title="item.title"></nut-cell>
</nut-cell-group>
</template>
<script setup>
import { ref } from 'vue'
const input = ref('')
const list = ref([
{ id: 1, title: '列表项 1' },
{ id: 2, title: '列表项 2' }
])
</script>说明:
- 京东风格
- 性能优化
- 主题定制
- 按需引入
图表组件库
ECharts
javascript
// 安装
npm install echarts
// 使用
<template>
<div ref="chartRef" style="width: 100%; height: 400px;"></div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import * as echarts from 'echarts'
const chartRef = ref(null)
onMounted(() => {
const chart = echarts.init(chartRef.value)
const option = {
title: {
text: 'ECharts 示例'
},
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [{
data: [150, 230, 224, 218, 135, 147, 260],
type: 'line'
}]
}
chart.setOption(option)
})
</script>说明:
- 功能丰富
- 性能优化
- 主题定制
- 按需引入
AntV
javascript
// 安装
npm install @antv/g2plot
// 使用
<template>
<div ref="chartRef" style="width: 100%; height: 400px;"></div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { Line } from '@antv/g2plot'
const chartRef = ref(null)
onMounted(() => {
const data = [
{ year: '2018', value: 3 },
{ year: '2019', value: 4 },
{ year: '2020', value: 3.5 },
{ year: '2021', value: 5 },
{ year: '2022', value: 4.9 }
]
const line = new Line(chartRef.value, {
data,
xField: 'year',
yField: 'value',
point: {
size: 5,
shape: 'diamond'
}
})
line.render()
})
</script>说明:
- 蚂蚁集团出品
- 性能优化
- 主题定制
- 按需引入
自定义组件
组件设计
javascript
// 组件设计原则
1. 单一职责
2. 可复用性
3. 可维护性
4. 可测试性
// 组件接口设计
interface Props {
// 必选属性
required: string;
// 可选属性
optional?: number;
// 默认值
default?: boolean;
// 验证器
validator?: (value: any) => boolean;
}
// 组件事件设计
interface Events {
// 更新事件
'update:modelValue': (value: any) => void;
// 自定义事件
'custom-event': (data: any) => void;
}说明:
- 设计原则
- 接口设计
- 事件设计
- 文档规范
组件封装
javascript
// 基础组件
<template>
<div class="base-component">
<slot></slot>
</div>
</template>
<script setup>
defineProps({
title: {
type: String,
required: true
}
})
</script>
// 业务组件
<template>
<div class="business-component">
<base-component :title="title">
<slot></slot>
</base-component>
</div>
</template>
<script setup>
import BaseComponent from './BaseComponent.vue'
defineProps({
title: {
type: String,
required: true
}
})
</script>说明:
- 基础组件
- 业务组件
- 组件复用
- 组件通信
组件测试
javascript
// 单元测试
import { mount } from '@vue/test-utils'
import MyComponent from './MyComponent.vue'
describe('MyComponent', () => {
test('renders properly', () => {
const wrapper = mount(MyComponent, {
props: {
title: 'Test Title'
}
})
expect(wrapper.text()).toContain('Test Title')
})
test('emits event', async () => {
const wrapper = mount(MyComponent)
await wrapper.find('button').trigger('click')
expect(wrapper.emitted('click')).toBeTruthy()
})
})
// 快照测试
test('matches snapshot', () => {
const wrapper = mount(MyComponent)
expect(wrapper.html()).toMatchSnapshot()
})说明:
- 单元测试
- 快照测试
- 测试覆盖率
- 测试工具
最佳实践
1. 组件选择
- 根据项目需求选择
- 考虑性能和体积
- 考虑维护成本
- 考虑团队熟悉度
2. 组件使用
- 按需引入
- 合理封装
- 统一管理
- 版本控制
3. 组件开发
- 遵循设计规范
- 编写完整文档
- 添加单元测试
- 性能优化
学习资源
官方文档
视频课程
- 慕课网
- 极客时间
- B站技术区
- YouTube 技术频道