設計思路
使用Element Plus的el-table組件展示人員數據
在姓名表頭添加搜索圖標按鈕
點擊按鈕彈出搜索對話框
在對話框中輸入姓名進行搜索
實現搜索功能并高亮匹配項
下面是完整的實現代碼:
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>人員管理系統 - Vue3 + Element Plus</title><!-- 引入Element Plus樣式 --><link rel="stylesheet" href="https://unpkg.com/element-plus/dist/index.css"><!-- 引入Element Plus圖標 --><link rel="stylesheet" href="https://unpkg.com/@element-plus/icons-vue/dist/index.css"><style>* {margin: 0;padding: 0;box-sizing: border-box;}body {font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);min-height: 100vh;padding: 20px;color: #333;}.container {max-width: 1200px;margin: 0 auto;padding: 20px;}header {text-align: center;margin-bottom: 30px;padding: 20px;background: linear-gradient(90deg, #1e3c72 0%, #2a5298 100%);border-radius: 12px;color: white;box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);}h1 {font-size: 2.5rem;margin-bottom: 10px;}.subtitle {font-size: 1.1rem;opacity: 0.9;}.card {background: white;border-radius: 12px;box-shadow: 0 6px 30px rgba(0, 0, 0, 0.1);padding: 25px;margin-bottom: 30px;transition: transform 0.3s ease, box-shadow 0.3s ease;}.card:hover {transform: translateY(-5px);box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15);}.search-container {display: flex;justify-content: flex-end;margin-bottom: 20px;}.search-btn {display: flex;align-items: center;background: linear-gradient(90deg, #1e3c72 0%, #2a5298 100%);color: white;border: none;padding: 10px 20px;border-radius: 8px;cursor: pointer;transition: all 0.3s ease;box-shadow: 0 4px 15px rgba(30, 60, 114, 0.3);}.search-btn:hover {transform: translateY(-2px);box-shadow: 0 6px 20px rgba(30, 60, 114, 0.4);}.search-btn i {margin-right: 8px;font-size: 18px;}.highlight {background-color: #ffeb3b;font-weight: bold;padding: 0 2px;border-radius: 3px;}.stats {display: flex;justify-content: space-between;margin-top: 20px;background: #f8f9fc;padding: 15px;border-radius: 8px;font-size: 0.95rem;}.stat-item {text-align: center;padding: 0 15px;}.stat-value {font-size: 1.4rem;font-weight: bold;color: #1e3c72;}.stat-label {color: #6c757d;font-size: 0.9rem;}.footer {text-align: center;margin-top: 30px;color: #6c757d;font-size: 0.9rem;}@media (max-width: 768px) {.stats {flex-direction: column;}.stat-item {margin-bottom: 15px;}}</style>
</head>
<body><div id="app"><div class="container"><header><h1>人員管理系統</h1><p class="subtitle">使用 Vue3 和 Element Plus 構建</p></header><main><div class="card"><div class="search-container"><button class="search-btn" @click="openSearchDialog"><i class="el-icon-search"></i> 搜索人員</button></div><el-table :data="filteredPersonnel" style="width: 100%" border stripe><el-table-column prop="id" label="ID" width="80" sortable></el-table-column><el-table-column label="姓名" sortable><template #header><span>姓名</span><el-button type="text" @click="openSearchDialog"><i class="el-icon-search" style="margin-left: 8px; font-size: 16px;"></i></el-button></template><template #default="scope"><span v-html="highlightSearchTerm(scope.row.name)"></span></template></el-table-column><el-table-column prop="position" label="職位" width="180"></el-table-column><el-table-column prop="department" label="部門" width="150"></el-table-column><el-table-column prop="email" label="郵箱" width="220"></el-table-column><el-table-column prop="phone" label="電話" width="150"></el-table-column><el-table-column label="狀態" width="120"><template #default="scope"><el-tag :type="scope.row.status === '在職' ? 'success' : 'danger'">{{ scope.row.status }}</el-tag></template></el-table-column></el-table><div class="stats"><div class="stat-item"><div class="stat-value">{{ totalPersonnel }}</div><div class="stat-label">總人數</div></div><div class="stat-item"><div class="stat-value">{{ activePersonnel }}</div><div class="stat-label">在職人員</div></div><div class="stat-item"><div class="stat-value">{{ filteredCount }}</div><div class="stat-label">搜索結果</div></div></div></div></main><!-- 搜索對話框 --><el-dialog v-model="searchDialogVisible" title="搜索人員" width="500px"><el-inputv-model="searchTerm"placeholder="請輸入人員姓名"clearable@keyup.enter="applySearch"><template #prefix><i class="el-icon-search"></i></template></el-input><div style="margin-top: 20px;"><el-button type="primary" @click="applySearch" style="width: 100%;"><i class="el-icon-search"></i> 搜索</el-button><el-button @click="clearSearch" style="width: 100%; margin-top: 10px;"><i class="el-icon-refresh"></i> 重置搜索</el-button></div><template #footer><div style="text-align: center; margin-top: 10px;"><el-button type="text" @click="searchDialogVisible = false">關閉</el-button></div></template></el-dialog><footer class="footer"><p>? 2023 人員管理系統 | 使用 Vue3 和 Element Plus 構建</p></footer></div></div><!-- 引入Vue 3 --><script src="https://unpkg.com/vue@3/dist/vue.global.js"></script><!-- 引入Element Plus --><script src="https://unpkg.com/element-plus/dist/index.full.js"></script><!-- 引入Element Plus圖標 --><script src="https://unpkg.com/@element-plus/icons-vue"></script><script>const { createApp, ref, computed } = Vue;const app = createApp({setup() {// 搜索對話框可見性const searchDialogVisible = ref(false);// 搜索關鍵詞const searchTerm = ref('');// 打開搜索對話框const openSearchDialog = () => {searchDialogVisible.value = true;};// 應用搜索const applySearch = () => {searchDialogVisible.value = false;};// 清除搜索const clearSearch = () => {searchTerm.value = '';applySearch();};// 模擬人員數據const personnelData = ref([{ id: 1, name: '張明', position: '前端工程師', department: '技術部', email: 'zhangming@example.com', phone: '13800138001', status: '在職' },{ id: 2, name: '李華', position: '后端工程師', department: '技術部', email: 'lihua@example.com', phone: '13800138002', status: '在職' },{ id: 3, name: '王芳', position: 'UI設計師', department: '設計部', email: 'wangfang@example.com', phone: '13800138003', status: '在職' },{ id: 4, name: '劉偉', position: '產品經理', department: '產品部', email: 'liuwei@example.com', phone: '13800138004', status: '在職' },{ id: 5, name: '陳靜', position: '測試工程師', department: '質量保障部', email: 'chenjing@example.com', phone: '13800138005', status: '在職' },{ id: 6, name: '趙陽', position: '運維工程師', department: '技術部', email: 'zhaoyang@example.com', phone: '13800138006', status: '離職' },{ id: 7, name: '錢浩', position: '項目經理', department: '項目管理部', email: 'qianhao@example.com', phone: '13800138007', status: '在職' },{ id: 8, name: '孫琳', position: '數據分析師', department: '數據分析部', email: 'sunlin@example.com', phone: '13800138008', status: '在職' },{ id: 9, name: '周濤', position: '移動開發工程師', department: '技術部', email: 'zhoutao@example.com', phone: '13800138009', status: '在職' },{ id: 10, name: '吳敏', position: 'HR專員', department: '人力資源部', email: 'wumin@example.com', phone: '13800138010', status: '在職' }]);// 過濾后的人員數據const filteredPersonnel = computed(() => {if (!searchTerm.value) {return personnelData.value;}const term = searchTerm.value.toLowerCase();return personnelData.value.filter(person => person.name.toLowerCase().includes(term));});// 高亮搜索關鍵詞const highlightSearchTerm = (name) => {if (!searchTerm.value) return name;const term = searchTerm.value;const regex = new RegExp(term, 'gi');return name.replace(regex, match => `<span class="highlight">${match}</span>`);};// 統計信息const totalPersonnel = computed(() => personnelData.value.length);const activePersonnel = computed(() => personnelData.value.filter(p => p.status === '在職').length);const filteredCount = computed(() => filteredPersonnel.value.length);return {searchDialogVisible,searchTerm,openSearchDialog,applySearch,clearSearch,filteredPersonnel,highlightSearchTerm,totalPersonnel,activePersonnel,filteredCount};}});// 注冊Element Plusapp.use(ElementPlus);// 注冊圖標組件const ElIcon = ElementPlus.ElIcon;app.component('el-icon', ElIcon);app.mount('#app');</script>
</body>
</html>