(14)Element Plus項目綜合案例


本系列教程目錄Vue3+Element Plus全套學習筆記-目錄大綱


文章目錄

  • 第3章 綜合案例
    • 3.1 搭建項目
      • 3.1.1 創建Vite工程
      • 3.1.2 配置路由
    • 3.2 登錄模塊頁面
      • 3.2.1 注冊頁面
      • 3.2.2 登錄頁面
      • 3.2.3 忘記密碼頁面
    • 3.3 導航設置
      • 3.3.1 頭部
      • 3.3.2 側邊欄與底部
        • 1)頭像部分
        • 2)折疊效果
        • 3)菜單列表
        • 4)路由配置
    • 3.4 儀表盤模塊
        • 1)主面板部分
        • 2)圖表部分
    • 3.5 用戶模塊
      • 3.5.1 用戶列表
        • 1)搜索表單
        • 2)表格組件
        • 3)分頁組件
      • 3.5.2 用戶詳情
        • 1)用戶詳情對話框
        • 2)綁定事件
      • 3.5.3 用戶關注列表
        • 1)關注列表
        • 2)分頁
      • 3.5.4 個人中心
    • 3.6 文章模塊
      • 3.6.1 文章列表
        • 1)搜索表單
        • 2)表格組件
        • 3)分頁組件
      • 3.6.2 發布文章
        • 1)發布文章對話框
        • 2)綁定事件
      • 3.6.3 文章詳情
        • 1)文章詳情對話框
        • 2)綁定事件
      • 3.6.4 我的收藏列表
    • 3.7 部門模塊
    • 3.8 會議模塊
      • 3.8.1 會議列表
        • 1)搜索表單
        • 2)表格組件
        • 3)分頁組件
      • 3.8.2 發布會議
        • 1)發布會議對話框
        • 2)綁定事件
      • 3.8.2 會議詳情對話框
        • 1)會議詳情對話框

第3章 綜合案例

3.1 搭建項目

3.1.1 創建Vite工程

1)創建Vite工程,輸入命令:

npm create vite進入項目npm install

2)安裝element plus、element plus icon依賴,并配置相關信息:

npm install element-plus
npm install @element-plus/icons-vue

3)配置相關信息(打開main.js):

import { createApp } from 'vue'// 導入ElementPlus組件
import ElementPlus from 'element-plus'// 導入ElementPlus樣式
import 'element-plus/dist/index.css'// 導入App組件
import App from './App.vue'// 導入ElementPlus圖標
import * as ElementPlusIconsVue from '@element-plus/icons-vue'// 創建Vue實例
const app = createApp(App)
app.use(ElementPlus)       // 使用ElementPlus組件
app.mount('#app')// 注冊ElementPlus圖標
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {app.component(key, component)
}

3.1.2 配置路由

1)安裝路由依賴:

npm install vue-router

2)創建src/router/index.js,配置路由信息:

// 導入VueRouter中的createRouter和createWebHashHistory函數
import {createRouter, createWebHashHistory} from 'vue-router'// 定義路由表
const routes = [// 訪問/login或者/都來到login.vue組件{path: '/login', component: () => import('../components/login.vue')},{path: '/', component: () => import('../components/login.vue')},
]// 創建路由實例
const router = createRouter({history: createWebHashHistory(),routes: routes
})// 導出路由
export default router

3)創建components/login.vue組件:

<script setup></script><template><div><h1>Login</h1></div></template><style scoped></style>

4)在main.js中配置路由:

...
// 導入路由
import router from './router/index.js'
// 創建Vue實例
const app = createApp(App)
app.use(router)           // 注冊路由
...

3.2 登錄模塊頁面

登錄模塊包括登錄頁面、忘記密碼頁面、注冊用戶頁面等三個頁面。

3.2.1 注冊頁面

效果如下:

1)在router/index.js中定義注冊組件路由:

{path: '/register',name: "register", component: () => import('../components/register.vue')}

2)編寫components/register.vue組件:

<template><div class="body"><div class="container"><h2>新用戶注冊</h2><el-text>請輸入您的信息</el-text><el-divider></el-divider><el-form ref="formRef" :model="form" :rules="rules" size="large"><el-form-item prop="email"><el-input v-model="form.email" placeholder="請輸入郵箱" prefix-icon="Message"></el-input></el-form-item><el-form-item prop="username"><el-input v-model="form.username" placeholder="請輸入用戶名" prefix-icon="User"></el-input></el-form-item><el-form-item prop="password"><el-input type="password" v-model="form.password" placeholder="請輸入密碼" prefix-icon="Lock"></el-input></el-form-item><el-form-item prop="confirmPassword"><el-input type="password" v-model="form.confirmPassword" placeholder="請再次輸入密碼"prefix-icon="Lock"></el-input></el-form-item><el-form-item><el-button type="primary" @click="sendEmail" :disabled="isDisabled">{{ buttonText }}</el-button></el-form-item><el-form-item><el-button type="success" style="width: 100%" @click="register">注冊</el-button></el-form-item><el-form-item><el-link type="primary" @click="$router.push('/login')">返回登錄</el-link></el-form-item></el-form></div></div></template>

3)css:

.body {/*布局*/display: flex;/*水平居中*/justify-content: center;/*垂直居中*/align-items: center;/*高度為 100vh(視窗高度)*/height: 100vh;/* 背景顏色(漸變)*/background: linear-gradient(135deg, #74ebd5 0%, #ACB6E5 100%);
}.container {width: 600px;margin: 0 auto;padding: 20px;background-color: #fff;text-align: center;
}

4)script:

import {reactive} from 'vue'
import {ref, computed, onUnmounted} from 'vue'
import {ElMessage, ElMessageBox} from "element-plus";// 表單的引用對象
const formRef = ref();// 表單數據
const form = reactive({email: '',username: '',password: '',confirmPassword: '',
})// 響應式數據
const isDisabled = ref(false)    // 按鈕禁用狀態
const remainingTime = ref(0)     // 剩余時間(秒)
let timer = null                 // 定時器實例// 計算按鈕顯示文本
const buttonText = computed(() => {return isDisabled.value? `${remainingTime.value}秒后重試`: '發送郵箱'
})// 發送郵件處理
const sendEmail = () => {// 校驗email字段formRef.value.validateField("email",(valid) => {if (valid) {// 表單驗證通過,發送郵件// 顯示成功提示ElMessage.success('郵箱已發送,請注意查收!')// 重置表單form.email = ''// 設置禁用狀態和倒計時isDisabled.value = trueremainingTime.value = 60// 啟動倒計時定時器timer = setInterval(() => {remainingTime.value -= 1// 倒計時結束后恢復按鈕狀態if (remainingTime.value <= 0) {clearInterval(timer)isDisabled.value = false}}, 1000)} else {// 表單驗證失敗,顯示錯誤信息ElMessage.error('表單驗證失敗,請檢查輸入!')}})
}// 組件卸載時清除定時器(防止內存泄漏)
onUnmounted(() => {if (timer) clearInterval(timer)
})// 表單校驗規則
const rules = {email: [{required: true, message: '請輸入郵箱', trigger: 'blur'},{type: 'email', message: '請輸入正確的郵箱格式', trigger: 'blur'}],username: [{required: true, message: '請輸入用戶名', trigger: 'blur'},{min: 3, max: 10, message: '用戶名長度在 3 到 10 個字符', trigger: 'blur'}],password: [{required: true, message: '請輸入密碼', trigger: 'blur'},{min: 6, max: 16, message: '密碼長度在 6 到 16 個字符', trigger: 'blur'}],confirmPassword: [{required: true, message: '請再次輸入密碼', trigger: 'blur'},{validator: (rule, value, callback) => {if (value !== form.password) {callback('兩次輸入的密碼不一致!')} else {callback()}}, trigger: 'blur'}]
}// 注冊事件
const register = () => {formRef.value.validate((valid) => {if (valid) {// 表單驗證通過,發送注冊請求// 注冊成功提示ElMessage.success('注冊成功!');} else {// 表單驗證失敗,顯示錯誤信息ElMessage.error('表單驗證失敗,請檢查輸入!')}})
}

3.2.2 登錄頁面

效果如下:

1)在router/index.js中定義組件路由:

{path: '/login',name: "login", component: () => import('../components/login.vue')}

2)編寫components/login.vue組件:

<template><div class="body"><div class="container"><h2>用戶登錄</h2><el-text>請輸入您的信息</el-text><el-divider></el-divider><el-form ref="formRef" :model="form" :rules="rules" size="large"><el-form-item prop="username"><el-input v-model="form.username" placeholder="請輸入用戶名" prefix-icon="User"></el-input></el-form-item><el-form-item prop="password"><el-input v-model="form.password" placeholder="請輸入密碼" type="password" prefix-icon="Lock"></el-input></el-form-item><el-form-item prop="checkCode"><el-row gutter="20" style="width: 100%;"><el-col :span="16"><el-input v-model="form.checkCode" placeholder="請輸入驗證碼" prefix-icon="Check"></el-input></el-col><el-col :span="6"><img src="../assets/checkCode.png" alt="" style="width: 100%;height: 40px "></el-col></el-row></el-form-item><el-form-item><el-checkbox v-model="form.remember">記住我</el-checkbox></el-form-item><el-form-item><el-button type="success" style="width: 100%" @click="login">登錄</el-button></el-form-item><el-form-item><el-row :gutter="20" style="width: 100%;"><el-col :span="12" style="text-align: left;"><el-link type="primary" :underline="false" @click="$router.push('/forget')">忘記密碼?</el-link></el-col><el-col :span="12" style="text-align: right;"><el-link type="primary" :underline="false" @click="$router.push('/register')">沒有賬號?</el-link></el-col></el-row></el-form-item></el-form></div></div></template>

3)css:

.body {/*布局*/display: flex;/*水平居中*/justify-content: center;/*垂直居中*/align-items: center;/*高度為 100vh(視窗高度)*/height: 100vh;/* 背景顏色(漸變)*/background: linear-gradient(135deg, #74ebd5 0%, #ACB6E5 100%);
}.container {width: 600px;margin: 0 auto;padding: 20px;background-color: #fff;text-align: center;
}

4)script:

import {ref, reactive} from 'vue';
import {ElMessage} from 'element-plus';
import {useRouter} from 'vue-router';// 初始化路由
const router = useRouter();// 表單的引用對象
const formRef = ref(null);// 表單數據對象
const form = reactive({username: '',password: '',checkCode: '',remember: '',
});// 表單驗證規則
const rules = {username: [{required: true, message: '請輸入用戶名', trigger: 'blur'},{min: 3, max: 10, message: '用戶名長度在 3 到 10 個字符', trigger: 'blur'},],password: [{required: true, message: '請輸入密碼', trigger: 'blur'},{min: 6, max: 16, message: '密碼長度在 6 到 16 個字符', trigger: 'blur'},],checkCode: [{required: true, message: '請輸入驗證碼', trigger: 'blur'},{min: 4, max: 4, message: '驗證碼長度為 4', trigger: 'blur'},],
};// 用戶登錄
const login = () => {// 登錄formRef.value.validate((valid) => {if (valid) {// 登錄成功ElMessage.success('登錄成功');// 跳轉到首頁router.push({name: 'dashboard'});} else {ElMessage.error('登錄失敗,請檢查輸入');}});
};

3.2.3 忘記密碼頁面

效果如下:

1)在router/index.js中定義組件路由:

{path: '/forget', name: "forget", component: () => import('../components/forget.vue')}

2)編寫components/forget.vue組件:

<template><div class="body"><div class="container"><h2>忘記密碼</h2><el-text>請輸入您的信息</el-text><el-divider></el-divider><el-form ref="formRef" :model="form" :rules="rules" size="large"><el-form-item prop="email"><el-input v-model="form.email" placeholder="請輸入郵箱" prefix-icon="Email"></el-input></el-form-item><el-form-item><el-button type="primary" style="width: 40%" @click="sendCheckCode">獲取驗證碼</el-button></el-form-item><el-form-item prop="checkCode"><el-input v-model="form.checkCode" placeholder="請輸入驗證碼" prefix-icon="Check"></el-input></el-form-item><el-form-item prop="newPassword"><el-input v-model="form.newPassword" placeholder="請輸入新密碼" type="password" prefix-icon="Lock"></el-input></el-form-item><el-form-item><el-row :gutter="20"><el-col :span="11"><el-button type="success" @click="resetPassword">重置密碼</el-button></el-col><el-col :span="11"><el-button @click="$router.push('/login')">返回登錄</el-button></el-col></el-row></el-form-item></el-form></div></div></template>

3)css:

.body {/*布局*/display: flex;/*水平居中*/justify-content: center;/*垂直居中*/align-items: center;/*高度為 100vh(視窗高度)*/height: 100vh;/* 背景顏色(漸變)*/background: linear-gradient(135deg, #74ebd5 0%, #ACB6E5 100%);
}.container {width: 600px;margin: 0 auto;padding: 20px;background-color: #fff;text-align: center;
}

4)script:

import { ref, reactive } from 'vue';
import { ElMessage } from 'element-plus';
import { useRouter } from 'vue-router';// 初始化路由實例
const router = useRouter();// 表單驗證
const formRef = ref(null);// 表單數據
const form = reactive({email: '',checkCode: '',newPassword: '',
});// 表單驗證規則
const rules = {email: [{ required: true, message: '請輸入郵箱', trigger: 'blur' },{ type: 'email', message: '請輸入正確的郵箱格式', trigger: 'blur' },],checkCode: [{ required: true, message: '請輸入驗證碼', trigger: 'blur' },{ min: 4, max: 4, message: '驗證碼長度為 4', trigger: 'blur' },],newPassword: [{ required: true, message: '請輸入新密碼', trigger: 'blur' },{ min: 6, max: 20, message: '密碼長度為 6-20 位', trigger: 'blur' },],
};// 發送驗證碼
const sendCheckCode = () => {formRef.value.validateField('email', (valid) => {if (valid) {// 發送驗證碼ElMessage.success('驗證碼已發送,請注意查收');}});
};// 重置密碼
const resetPassword = () => {formRef.value.validate((valid) => {if (valid) {// 重置密碼ElMessage.success('密碼重置成功,請重新登錄');router.push("/login");}});
};

3.3 導航設置

3.3.1 頭部

如圖所示:

1)定義components/views/home.vue組件:

<template><el-container style="height: 100vh"><el-header style="background: #409EFF; color: white">Header</el-header><el-container><el-aside width="200px" style="background: #545c64; color: white">Aside</el-aside><el-main>Main Content</el-main></el-container><el-footer style="background: #909399; color: white">Footer</el-footer></el-container></template>

2)在router/index.js中添加路由:

{path: '/views/', name: "home", component: () => import('../components/views/home.vue')}

3)頭部布局:

<!-- *************************************************頭部布局************************************************* -->
<el-header><div class="el-header-box"><el-row style="width: 100%"><el-col :span="12" style="text-align: left"><el-link to="/views/home" :underline="false" @click="$router.push('/views/dashboard')">協同會議平臺</el-link></el-col><el-col :span="12" style="text-align: right"><el-link to="/login" :underline="false" @click="$router.push('/login')">退出</el-link></el-col></el-row></div></el-header>

4)css:

.el-header-box {display: flex;align-items: center;height: 100%;border-bottom: 1px solid #eee;
}

3.3.2 側邊欄與底部

效果如下:

1)頭像部分

效果如下:

1)布局代碼:

<!-- *************************************************主體部分 ************************************************* -->
<el-container>
<!-- *************************************************主體-側邊欄部分  ************************************************* --><el-aside><el-menu default-active="/views/dashboard" mode="vertical" :router="true"><div class="el-aside-avatar"><!-- *************************************************頭像部分 ************************************************* --><el-row style="width: 180px"><el-col :span="12"><router-link to="/views/user/update"><el-avatar src="/src/assets/avatar.jpg" style="width: 70px; height: 70px"></el-avatar></router-link></el-col><el-col :span="4" v-show="!isCollapse"><el-tag type="success" size="large">小灰</el-tag><el-tag type="primary" size="large" style="margin-top: 10px;">研發部</el-tag></el-col></el-row></div></el-menu></el-aside><!--   主體中心部分   --><el-main><!--    當點擊菜單時,路由切換到對應的頁面    --><h1>Dashboard</h1></el-main></el-container>

2)css:

.el-aside-avatar {padding: 10px;
}
2)折疊效果

效果如下:

1)布局代碼:

<!-- *************************************************主體部分 ************************************************* -->
<el-container><!-- *************************************************主體-側邊欄部分  ************************************************* --><el-aside class="el-aside-demo"><!-- 折疊按鈕   --><el-radio-group v-model="isCollapse" style="margin-bottom: 20px"><el-radio-button :value="true">隱藏</el-radio-button><el-radio-button :value="false">展開</el-radio-button></el-radio-group><el-menu default-active="/views/dashboard" :collapse="isCollapse"mode="vertical" :router="true"><div class="el-aside-avatar"><!-- *************************************************頭像部分 ************************************************* --><el-row style="width: 180px" v-show="!isCollapse"><!--   沒折疊時顯示的頭像信息   --><el-col :span="12"><router-link to="/views/user/update"><el-avatar src="/src/assets/avatar.jpg" style="width: 70px; height: 70px"></el-avatar></router-link></el-col><el-col :span="4"><el-tag type="success" size="large">小灰</el-tag><el-tag type="primary" size="large" style="margin-top: 10px;">研發部</el-tag></el-col></el-row><el-row  v-show="isCollapse"><!--   折疊時顯示的頭像信息   --><el-col :span="24" style="text-align: center"><router-link to="/views/user/update"><el-avatar src="/src/assets/avatar.jpg" style="width: 100%; height: 100%"></el-avatar></router-link></el-col></el-row></div></el-menu></el-aside><!-- *************************************************主體-中心部分  ************************************************* --><el-main><!--    當點擊菜單時,路由切換到對應的頁面    --><h1>Dashboard</h1></el-main></el-container>

2)css:

.el-aside-demo {/* 寬度自適應 */--el-aside-width: auto;
}

3)script:

//  控制側邊欄折疊是否折疊
const isCollapse = ref(false);
3)菜單列表

效果如下:

1)布局代碼:

<!-- *************************************************菜單部分 ************************************************* -->
<el-menu-item index="/views/dashboard"><el-icon><location/></el-icon><span slot="title">主頁</span></el-menu-item><el-sub-menu><template #title><el-icon><user/></el-icon><span>用戶列表</span></template><el-menu-item index="/views/user">查看用戶</el-menu-item><el-menu-item index="/views/user/my_user">我關注的用戶</el-menu-item></el-sub-menu><el-sub-menu index="3"><template #title><el-icon><Document/></el-icon><span>文章管理</span></template><el-menu-item index="/views/article">文章列表</el-menu-item><el-menu-item index="/views/article/article_collect">我的收藏</el-menu-item></el-sub-menu><el-menu-item index="/views/department"><el-icon><OfficeBuilding/></el-icon><span slot="title">部門列表</span></el-menu-item><el-menu-item index="/views/meeting"><el-icon><Coordinate/></el-icon><span slot="title">會議系統</span></el-menu-item>
4)路由配置

當點擊側邊欄的菜單項時,右邊的主體部分內容需要切換到具體的路由。如圖所示:

1)定義views/home組件的子路由:

{path: '/views/',name:"home", component: () => import('../components/views/home.vue'),children: [{path: 'dashboard',name:"dashboard",  component: () => import('../components/views/dashboard/index.vue')},{path: 'article', name:"article", component: () => import('../components/views/article/index.vue')},{path: 'article/favorite',name:"articleFavorite", component: () => import('../components/views/article/article_favorite.vue')},{path: 'department', name:"department", component: () => import('../components/views/department/index.vue')},{path: 'meeting', name:"meeting", component: () => import('../components/views/meeting/index.vue')},{path: 'user',name:"user", component: () => import('../components/views/user/index.vue')},{path: 'user/follow', name:"userFollow", component: () => import('../components/views/user/user_follow.vue')},{path: 'user/update', name:"myUser", component: () => import('../components/views/user/user_update.vue')},]
},

2)定義組件:

3)在home.vue組件中的布局主體部分替換成路由組件:

<!--   主體中心部分   -->
<el-main><!--    當點擊菜單時,路由切換到對應的頁面    --><router-view />
</el-main>

3.4 儀表盤模塊

效果如圖:

1)主面板部分

效果如下:

1)布局代碼:

<!-- *************************************************主面板************************************************* -->
<h2>主面板</h2><el-row :gutter="20"><el-col :xs="24" :sm="12" :md="8" :lg="6"><el-card class="card-item"><h3>新增用戶</h3><el-progress :percentage="100" :format="format"/></el-card></el-col><el-col :xs="24" :sm="12" :md="8" :lg="6"><el-card class="card-item"><h3>新增文章</h3><el-progress :percentage="54" :format="format"/></el-card></el-col><el-col :xs="24" :sm="12" :md="8" :lg="6"><el-card class="card-item"><h3>新開會議</h3><el-progress :percentage="38" :format="format"/></el-card></el-col></el-row>

2)script:

// 格式化百分比
const format = (percentage) => (percentage === 100 ? '100+' : percentage)
2)圖表部分

效果如下:

1)安裝echarts依賴:

npm install echarts

2)布局代碼:

<!-- *************************************************圖標部分************************************************* -->
<div id="charts" class="charts"></div>

3)css:

.charts {width: 80%;height: 400px;margin-top: 20px
}

4)script:

// 導入echarts
import * as echarts from 'echarts'
import {ref, onMounted} from 'vue'// 計算近七日日期
var date = new Date();
var days = [];for (var i = -6; i <= 0; i++) {date.setDate(date.getDate() + i);var month = date.getMonth() + 1;var day = date.getDate();if (month < 10) month = "0" + month;if (day < 10) day = "0" + day;days.push(month + "." + day);date.setDate(date.getDate() - i);
}// 圖表渲染數據
const option = ref({title: {text: '數據匯總'},tooltip: {trigger: 'axis', axisPointer: {type: 'cross', label: {backgroundColor: '#aaaaff'}}},legend: {data: ['新增用戶', '新增文章', '新開會議']},toolbox: {feature: {saveAsImage: {}}},grid: {left: '3%', right: '4%', bottom: '3%', containLabel: true},xAxis: [{type: 'category', boundaryGap: false, data: days}],yAxis: [{type: 'value'}],series: [{name: '新增用戶', type: 'line', stack: '總量', areaStyle: {}, data: [56, 21, 24, 34, 61, 54, 100]},{name: '新增文章', type: 'line', stack: '總量', areaStyle: {}, data: [29, 40, 89, 54, 42, 69, 54]},{name: '新開會議', type: 'line', stack: '總量', areaStyle: {}, data: [31, 28, 49, 61, 39, 72, 38]}]
})// 圖表實例
let myChart = null// 圖表渲染
onMounted(() => {const chartDom = document.getElementById('charts')if (!chartDom) return// 初始化圖表myChart = echarts.init(chartDom)myChart.setOption(option.value)// 窗口變化時自適應window.addEventListener('resize', () => myChart?.resize())
})

3.5 用戶模塊

3.5.1 用戶列表

1)搜索表單

效果如下:

1)布局代碼如下:

<!-- *************************************************表單搜索************************************************* -->
<h3>用戶列表</h3><el-row><el-col :span="15"><el-form inline size="large"><el-form-item label="用戶名"><el-input v-model="searchFrom.username" placeholder="請輸入搜索內容"></el-input></el-form-item><el-form-item><el-button type="primary" @click="search">搜索</el-button></el-form-item></el-form></el-col></el-row>

2)script:

import {reactive} from 'vue'
import {ElMessage, ElMessageBox} from 'element-plus'//****************************************搜索表單********************************************//
// 表單搜索條件
const searchFrom = reactive({username: ''
})// 表單搜索
const search = () => {ElMessage.success(`搜索條件${searchFrom.username}`)
}
2)表格組件

效果如下:

1)布局代碼:

<!-- *************************************************數據展示部分************************************************* -->
<el-table :data="users" border style="width: 100%;height: 300px"><el-table-column prop="id" label="ID" width="50"></el-table-column><el-table-column prop="username" label="用戶名" width="120"></el-table-column><el-table-column prop="realName" label="真實姓名" width="120"></el-table-column><el-table-column prop="sex" label="性別" width="80"><template #default="scope"><el-tag :type="scope.row.sex === '0'? 'success' : 'warning'">{{ scope.row.sex === '0' ? '男' : '女' }}</el-tag></template></el-table-column><el-table-column prop="age" label="年齡" width="80"></el-table-column><el-table-column prop="email" label="郵箱" width="200"></el-table-column><el-table-column prop="phone" label="手機號" width="150"></el-table-column><el-table-column prop="info" label="簡介" width="300"></el-table-column><el-table-column prop="isFollowed" label="加關注" width="80" fixed="right"><template #default="scope"><el-switch v-model="scope.row.isFollowed" @click="addFollow(scope.row.id)" :active-value="1":inactive-value="0"></el-switch></template></el-table-column><el-table-column label="操作" width="150" fixed="right"><template #default="scope"><el-button type="text" @click="showDialog(scope.row)">查看詳情</el-button></template></el-table-column></el-table>

2)script:

const users = reactive([{id: 1,username: 'admin',realName: '管理員',sex: '0',age: 30,email: 'admin@example.com',phone: '12345678901',info: '這是一段簡介',isFollowed: 1},{id: 2,username: 'xiaohui',realName: '小灰',sex: '0',age: 22,email: 'xiaohui@example.com',phone: '12345678902',info: '這是一段簡介',isFollowed: 0},{id: 3,username: 'xiaolan',realName: '小藍',sex: '1',age: 20,email: 'xiaolan@example.com',phone: '12345678903',info: '這是一段簡介',isFollowed: 1},{id: 4,username: '小綠',realName: 'xiaolv',sex: '1',age: 20,email: 'xiaolv@example.com',phone: '12345678903',info: '這是一段簡介',isFollowed: 0},{id: 5,username: 'xiaoming',realName: '小明',sex: '0',age: 20,email: 'xiaoming@example.com',phone: '12345678903',info: '這是一段簡介',isFollowed: 1}
])
// 編輯按鈕
const showDialog = (scope) => {ElMessage.success(`查看【${scope.id}`)// 顯示編輯對話框detailDialogVisible.value = true
}// 刪除按鈕
const deleteRow = (id) => {ElMessageBox.confirm('確認刪除該行嗎?').then(() => {ElMessage.success(`刪除成功【${id}`)// console.log(row)}).catch(() => {// cancel})
}// 加關注
const addFollow = (id) => {ElMessage.success(`關注【${id}`)
}
3)分頁組件

效果如下:

1)布局代碼:

<!-- *************************************************分頁組件************************************************* -->
<div style="margin-top: 20px;display: flex;justify-content: center;"><el-paginationv-model:current-page="currentPage"v-model:page-size="pageSize":page-sizes="[3, 5, 10]"size="large"layout="total, sizes, prev, pager, next, jumper":total="400"@size-change="handleSizeChange"@current-change="handleCurrentChange"/>
</div>

2)script:

//****************************************分頁組件********************************************//
// 當前頁
const currentPage = ref(1)
// 頁大小
const pageSize = ref(10)// 當頁大小發生改變時執行
const handleSizeChange = (val) => {ElMessage.success(`每頁顯示:${val}`)
}// 當當前頁發生改變時執行
const handleCurrentChange = (val) => {ElMessage.success(`當前頁碼:${val}`)
}

3.5.2 用戶詳情

1)用戶詳情對話框

當點擊某一行的“查看詳情”按鈕時應該彈出對話框,展示用戶信息數據。

效果如下:

1)布局代碼:

<el-dialog title="用戶詳情" v-model="detailDialogVisible" width="60%" top="0vh"><el-divider/><el-form :model="userForm" label-width="80px" :disabled="true"><el-form-item label="頭像"><el-row style="width: 100%;"><el-col :span="6"><el-avatar :size="84" shape="square" :src="userForm.pic"></el-avatar></el-col><el-col :span="18"><el-row style="width: 100%;" gutter="20"><el-col :span="10"><el-text size="large">粉絲數:<el-tag type="danger">{{ userForm.fans }}</el-tag></el-text></el-col><el-col :span="10"><el-text><!--  嵌入一個子form,否則該switch控件會被處于禁止狀態--><el-form>加關注:<el-switch v-model="userForm.isFollowed" @click="addFollow(userForm.id)":active-value="1" :inactive-value="0"></el-switch></el-form></el-text></el-col></el-row><el-divider style="width: 60%;"/><el-row style="width: 100%;" gutter="20"><el-col :span="10"><el-text>關注數:<el-tag type="success">{{ userForm.follows }}</el-tag></el-text></el-col><el-col :span="10"><el-text>瀏覽量:<el-tag type="primary">{{ userForm.browseCount }}</el-tag></el-text></el-col></el-row></el-col></el-row></el-form-item><el-form-item label="用戶名"><el-input v-model="userForm.username"></el-input></el-form-item><el-form-item label="真實姓名"><el-input v-model="userForm.realName"></el-input></el-form-item><el-form-item label="所在部門"><el-select v-model="userForm.deptName"><el-option :value="userForm.deptName">{{ userForm.deptName }}</el-option></el-select></el-form-item><el-form-item label="性別"><el-radio-group v-model="userForm.sex"><el-radio value="0">男</el-radio><el-radio value="1">女</el-radio></el-radio-group></el-form-item><el-form-item label="年齡"><el-input-number v-model="userForm.age"></el-input-number></el-form-item><el-form-item label="郵箱"><el-input v-model="userForm.email"></el-input></el-form-item><el-form-item label="手機號"><el-input v-model="userForm.phone"></el-input></el-form-item><el-form-item label="簡介"><el-input type="textarea" v-model="userForm.info"></el-input></el-form-item><el-form-item label="注冊時間"><el-input v-model="userForm.registerTime"></el-input></el-form-item><el-form-item label="登錄時間"><el-input v-model="userForm.loginTime"></el-input></el-form-item><el-form-item label="是否私密"><el-switch v-model="userForm.isSecret" active-value="0" inactive-value="1"></el-switch></el-form-item></el-form><el-divider/><div style="text-align: center"><el-button :icon="CircleClose" @click="dialogVisible = false" type="danger">關閉窗口</el-button></div></el-dialog>

2)script:

//****************************************會議詳情********************************************//
// 編輯對話框是否顯示
const detailDialogVisible = ref(false)// 用戶數據
const userForm = reactive({id: "1",username: 'xiaohui',realName: '小灰',sex: '0',age: '20',email: 'xiaohui@example.com',phone: '110',info: '我是大帥哥',pic: '/src/assets/avatar.jpg',registerTime: '2030-10-10 10:10:10',loginTime: '2030-10-10 10:10:10',isSecret: '0',deptName: "研發部",isFollowed: 1,fans: 798,follows: 148,browseCount: 102400
})// 編輯按鈕
const showDialog = (scope) => {ElMessage.success(`查看【${scope.id}`)// 顯示編輯對話框detailDialogVisible.value = true
}// 加關注
const addFollow = (id) => {ElMessage.success(`關注【${id}`)
}
2)綁定事件

給“編輯”按鈕綁定點擊事件:

<el-table-column label="操作" width="150" fixed="right"><template #default="scope"><el-button type="text" @click="showDialog(scope.row)">查看詳情</el-button></template></el-table-column>

3.5.3 用戶關注列表

1)關注列表

1)布局代碼:

<!-- *************************************************用戶列表************************************************* -->
<h3>我的關注列表</h3><el-table :data="tableData" style="width: 100%;height: 300px"><el-table-column prop="realName" label="姓名"></el-table-column><el-table-column label="操作" fixed="right" width="150"><template #default="scope"><el-button type="danger" @click="unFollow(scope.row.id)">取消關注</el-button></template></el-table-column></el-table>

2)script:

import {ElMessage, ElMessageBox} from "element-plus";
//****************************************用戶列表********************************************//
const tableData = [{id: 1,realName: '小灰'},{id: 2,realName: '小藍'},{id: 3,realName: '小綠'},{id: 4,realName: '小紅'},{id: 5,realName: '小明'},{id: 6,realName: '小龍'}
]// 取消關注
const unFollow = (id) => {ElMessageBox.confirm('確定取消關注該用戶嗎?').then(() => {ElMessage.success(`取消關注成功【${id}`)})
}
2)分頁

1)布局代碼:

<!-- *************************************************分頁組件************************************************* -->
<div style="margin-top: 20px;display: flex;justify-content: center;"><el-paginationv-model:current-page="currentPage"v-model:page-size="pageSize":page-sizes="[3, 5, 10]"size="large"layout="total, sizes, prev, pager, next, jumper":total="400"@size-change="handleSizeChange"@current-change="handleCurrentChange"/>
</div>

2)script:

//****************************************分頁組件********************************************//
// 當前頁
const currentPage = ref(1)
// 頁大小
const pageSize = ref(10)// 當頁大小發生改變時執行
const handleSizeChange = (val) => {ElMessage.success(`每頁顯示:${val}`)
}// 當當前頁發生改變時執行
const handleCurrentChange = (val) => {ElMessage.success(`當前頁碼:${val}`)
}

3.5.4 個人中心

當點擊側邊欄中的“頭像”時,進入個人中心頁面。

效果如下:

1)注意修改/src/components/home.vue組件中的頭像路由地址:

2)在/src/router/index.js文件中的home組件中定義子路由:

{path: 'user/update', name:"userUpdate", component: () => import('../components/views/user/user_update.vue')}

3)定義/src/components/views/user/update.vue組件

<template><h3>個人中心</h3><el-form ref="form" :model="userForm" label-width="100px" style="width: 80%"><el-form-item label="頭像"><el-row style="width: 100%;"><el-col :span="6"><el-upload action="http://localhost:3000/upload":on-success="handleAvatarSuccess"><img v-if="userForm.pic" :src="userForm.pic" width="70"/><el-icon v-else class="avatar-uploader-icon"><Plus/></el-icon></el-upload></el-col><el-col :span="18"><el-row style="width: 100%;" gutter="20"><el-col :span="8"><el-text size="large">粉絲數:<el-tag type="danger">{{ userForm.fans }}</el-tag></el-text></el-col><el-col :span="8"><el-text>關注數:<el-tag type="success">{{ userForm.follows }}</el-tag></el-text></el-col><el-col :span="8"><el-text>瀏覽量:<el-tag type="primary">{{ userForm.browseCount }}</el-tag></el-text></el-col></el-row><el-divider style="width: 90%;"/></el-col></el-row></el-form-item><el-form-item label="用戶名"><el-input v-model="userForm.username"></el-input></el-form-item><el-form-item label="真實姓名"><el-input v-model="userForm.realName"></el-input></el-form-item><el-form-item label="部門名稱"><el-select v-model="userForm.deptId" placeholder="請選擇部門"><el-option v-for="item in deptList" :key="item.id" :label="item.name" :value="item.id"></el-option></el-select></el-form-item><el-form-item label="性別"><el-radio-group v-model="userForm.sex"><el-radio :value="0">男</el-radio><el-radio :value="1">女</el-radio></el-radio-group></el-form-item><el-form-item label="年齡"><el-input-number v-model="userForm.age"></el-input-number></el-form-item><el-form-item label="郵箱"><el-input v-model="userForm.email"></el-input></el-form-item><el-form-item label="手機號"><el-input v-model="userForm.phone"></el-input></el-form-item><el-form-item label="簡介"><el-input type="textarea" v-model="userForm.info"></el-input></el-form-item><el-form-item label="注冊時間"><el-input v-model="userForm.registerTime" disabled></el-input></el-form-item><el-form-item label="登錄時間"><el-input v-model="userForm.loginTime" disabled></el-input></el-form-item><el-form-item label="是否私密"><el-switch v-model="userForm.isSecret" active-value="0" inactive-value="1"></el-switch></el-form-item><el-form-item><el-button type="primary" @click="update">保存</el-button></el-form-item></el-form></template>

2)script:

import {reactive} from 'vue'
import {Plus} from "@element-plus/icons-vue";
import {ElMessage} from "element-plus";
import { useRouter } from 'vue-router'
let router = useRouter();   // 創建路由實例// 定義用戶信息表單
const userForm = reactive({username: 'xiaohui',realName: '小灰',deptId: 2,sex: 0,age: 20,email: 'xiaohui@example.com',phone: '13800138000',info: '大家好,我叫小灰,我今年20歲,歡迎來到我的空間,方便的話點個小愛心哦~',registerTime: '2021-01-01 00:00:00',loginTime: '2021-01-01 00:00:00',isSecret: 0,pic: '/src/assets/avatar.jpg',fans: 478,follows: 124,browseCount: 142714
})// 定義部門列表
const deptList = reactive([{id: 1,name: '開發部'},{id: 2,name: '測試部'},{id: 3,name: '運營部'}
])// 上傳用戶頭像
const handleAvatarSuccess = (res) => {ElMessage.success('上傳成功')
}// 保存用戶信息
const update = () => {ElMessage.success(`保存成功${userForm.username}`)// 跳轉到用戶列表組件router.push({name: 'user'})
}

3.6 文章模塊

3.6.1 文章列表

1)搜索表單

效果如下:

1)布局代碼:

<!-- *************************************************條件搜索************************************************* -->
<h3>文章列表</h3><el-row style="width: 100%;"><el-col :span="12"><el-form inline size="large"><el-form-item label="文章標題"><el-input v-model="searchForm.title" placeholder="請輸入搜索內容"></el-input></el-form-item><el-form-item><el-button type="primary" @click="search">搜索</el-button></el-form-item></el-form></el-col><el-col :span="12" style="text-align: right;"><el-button type="primary" @click="addDialogVisible = true" size="large">新增文章</el-button></el-col></el-row>

2)script:

//****************************************搜索表單********************************************//
// 搜索條件
const searchForm = reactive({title: ''
});// 搜索方法
const search = () => {ElMessage.success(`搜索成功${searchForm.title}`);
};
2)表格組件

效果如下:

1)布局代碼:

<!-- 文章列表  -->
<div><el-card v-for="(article, index) in articles" :key="index" style="margin-bottom: 20px;"><el-link type="primary" :underline="false">如何成為一名Java工程師?</el-link><p><el-text tag="strong">作者:</el-text><el-tag>{{ article.publishUser }}</el-tag></p><p><el-text tag="strong">時間:</el-text><el-tag type="success">{{ article.publishDate }}</el-tag></p><el-text>{{article.content}}</el-text></el-card></div>

2)script:

//****************************************文章列表********************************************//
const articles = [{id: '1',title: '如何成為一名Java工程師?',publishUser: '小灰',publishDate: '2030-01-01 10:00:00',content: '文章內容'},{id: '2',title: '如何成為一名Java工程師?',publishUser: '小藍',publishDate: '2030-01-01 10:00:00',content: '文章內容'}
];
3)分頁組件

效果如下:

1)布局代碼:

<!-- *************************************************分頁組件************************************************* -->
<div style="margin-top: 20px;display: flex;justify-content: center;"><el-paginationv-model:current-page="currentPage"v-model:page-size="pageSize":page-sizes="[3, 5, 10]"size="large"layout="total, sizes, prev, pager, next, jumper":total="400"@size-change="handleSizeChange"@current-change="handleCurrentChange"/>
</div>

2)script:

//****************************************分頁組件********************************************//
// 當前頁
const currentPage = ref(1)
// 頁大小
const pageSize = ref(10)// 當頁大小發生改變時執行
const handleSizeChange = (val) => {ElMessage.success(`每頁顯示:${val}`)
}// 當當前頁發生改變時執行
const handleCurrentChange = (val) => {ElMessage.success(`當前頁碼:${val}`)
}

3.6.2 發布文章

1)發布文章對話框

當點擊“發布文章”按鈕時應該彈出對話框,讓用戶填寫文章數據。

效果如下:

1)布局代碼:

<!-- *************************************************新增文章彈窗************************************************* -->
<el-dialog title="發布文章" v-model="addDialogVisible" style="width: 60%;height: 50%;"><el-divider/><el-form ref="form" :model="articleForm" label-width="80px"><el-form-item label="文章標題"><el-input v-model="articleForm.title" placeholder="請輸入文章標題"></el-input></el-form-item><el-form-item label="文章內容"><el-input type="textarea" :rows="5" v-model="articleForm.content" placeholder="請輸入文章內容"></el-input></el-form-item></el-form><el-divider/><div slot="footer" class="dialog-footer"><el-button type="primary" @click="add">確 定</el-button><el-button @click="addDialogVisible = false">取 消</el-button></div></el-dialog>

2)script:

//****************************************發布文章********************************************//
// 新增文章彈窗是否顯示
const addDialogVisible = ref(false);// 文章對象
const articleForm = reactive({title: '',content: ''
});// 新增文章方法
const add = () => {ElMessage.success(`新增文章成功:${JSON.stringify(articleForm)}`);addDialogVisible.value = false;console.log(articleForm);
};
2)綁定事件

給“新增文章”按鈕綁定點擊事件:

<el-button type="primary" @click="addDialogVisible = true" size="large">發布文章</el-button>

3.6.3 文章詳情

1)文章詳情對話框

當點擊某篇文章時,查詢文章詳情。

效果如下:

1)布局代碼:

<!-- *************************************************文章詳情彈窗************************************************* -->
<el-dialog title="文章詳情" v-model="detailDialogVisible" width="60%" top="5vh"><div style="position: relative"><h2 style="text-align: center">如何做一名合格的Java工程師</h2><el-button style="position: absolute;top:0;right: 10px;" type="success" @click="addFavorite(articleDetail.id)">收藏文章</el-button></div><el-divider/><el-card><el-row><el-col :span="3"><strong><el-icon><User/></el-icon>發布人:</strong></el-col><el-col :span="12">{{ articleDetail.publishUser }}</el-col></el-row><el-divider style="width:30%;margin: 10px 0"/><el-row><el-col :span="3"><strong><el-icon><Timer/></el-icon>發布時間:</strong></el-col><el-col :span="12">{{ articleDetail.publishDate }}</el-col></el-row><el-divider style="width:30%;margin: 10px 0"/><el-row><el-col :span="3"><strong><el-icon><Reading/></el-icon>瀏覽次數:</strong></el-col><el-col :span="12">{{ articleDetail.browseCount }}</el-col></el-row><el-divider style="width:30%;margin: 10px 0"/><el-row><el-col :span="3"><strong><el-icon><StarFilled/></el-icon>收藏次數:</strong></el-col><el-col :span="12">{{ articleDetail.favoriteCount }}</el-col></el-row><el-divider style="width:30%;margin: 10px 0"/><p><strong><el-icon><Document/></el-icon>文章內容:</strong></p><el-input type="textarea" :rows="10" v-model="articleDetail.content" disabled></el-input></el-card><el-divider/><div><p><strong><el-icon><UserFilled/></el-icon>您關注的用戶也收藏過這篇文章:</strong></p><el-button v-for="(user, index) in articleDetail.favoriteList">{{ user.realName }}</el-button></div><el-divider/><div style="text-align: center"><el-button type="danger" @click="detailDialogVisible = false"><el-icon><Close/></el-icon>關閉窗口</el-button></div></el-dialog>

2)script:

//****************************************文章詳情********************************************//
// 文章詳情彈窗是否顯示
const detailDialogVisible = ref(false);// 文章詳情對話框顯示
const showDetail = (id) => {ElMessage.success(`顯示文章詳情:${id}`);detailDialogVisible.value = true;
}// 文章詳情
const articleDetail = reactive({id: 1,title: '如何成為一名Java工程師?',content: '如何成為一名Java工程師如何成為一名Java工程師如何成為一名Java工程師如何成為一名Java工程師',publishUser: '小灰',publishDate: '2030-01-01 10:00:00',collectors: ['小灰', '小藍'],favoriteCount: 89,browseCount: 1246,favoriteList: [{id: "1", realName: '小灰'},{id: "2", realName: '小藍'},{id: "3", realName: '小綠'},]
});// 添加/取消收藏
const addFavorite = (id) => {ElMessage.success(`收藏成功:${articleDetail.id}`);
};
2)綁定事件

在文章列表中,給文章標題添加點擊事件:

<el-link type="primary" :underline="false" @click="showDetail(article.id)">如何成為一名Java工程師?</el-link>

3.6.4 我的收藏列表

我的收藏頁面整體布局和文章列表頁面一致,代碼可以參考文章列表。

效果如下:

1)布局代碼:

<template><!-- *************************************************條件搜索************************************************* --><h3>我收藏的文章</h3><el-row style="width: 100%;"><el-col :span="12"><el-form inline size="large"><el-form-item label="文章標題"><el-input v-model="searchForm.title" placeholder="請輸入搜索內容"></el-input></el-form-item><el-form-item><el-button type="primary" @click="search">搜索</el-button></el-form-item></el-form></el-col></el-row><!-- *************************************************文章列表************************************************* --><div><el-card v-for="(article, index) in articles" :key="index" style="margin-bottom: 20px;"><el-link type="primary" :underline="false" @click="showDetail(article.id)">如何成為一名Java工程師?</el-link><p><el-text tag="strong"><el-icon><User/></el-icon>作者:</el-text><el-tag>{{ article.publishUser }}</el-tag></p><p><el-text tag="strong"><el-icon><Timer/></el-icon>發布時間:</el-text><el-tag type="success">{{ article.publishDate }}</el-tag></p><el-text>{{ article.content }}</el-text></el-card></div><!-- *************************************************分頁組件************************************************* --><div style="margin-top: 20px;display: flex;justify-content: center;"><el-paginationv-model:current-page="currentPage"v-model:page-size="pageSize":page-sizes="[3, 5, 10]"size="large"layout="total, sizes, prev, pager, next, jumper":total="400"@size-change="handleSizeChange"@current-change="handleCurrentChange"/></div><!-- *************************************************文章詳情彈窗************************************************* --><el-dialog title="文章詳情" v-model="detailDialogVisible" width="60%" top="5vh"><div style="position: relative"><h2 style="text-align: center">如何做一名合格的Java工程師</h2><el-button style="position: absolute;top:0;right: 10px;" type="success" @click="addFavorite(articleDetail.id)">收藏文章</el-button></div><el-divider/><el-card><el-row><el-col :span="3"><strong><el-icon><User/></el-icon>發布人:</strong></el-col><el-col :span="12">{{ articleDetail.publishUser }}</el-col></el-row><el-divider style="width:30%;margin: 10px 0"/><el-row><el-col :span="3"><strong><el-icon><Timer/></el-icon>發布時間:</strong></el-col><el-col :span="12">{{ articleDetail.publishDate }}</el-col></el-row><el-divider style="width:30%;margin: 10px 0"/><el-row><el-col :span="3"><strong><el-icon><Reading/></el-icon>瀏覽次數:</strong></el-col><el-col :span="12">{{ articleDetail.browseCount }}</el-col></el-row><el-divider style="width:30%;margin: 10px 0"/><el-row><el-col :span="3"><strong><el-icon><StarFilled/></el-icon>收藏次數:</strong></el-col><el-col :span="12">{{ articleDetail.favoriteCount }}</el-col></el-row><el-divider style="width:30%;margin: 10px 0"/><p><strong><el-icon><Document/></el-icon>文章內容:</strong></p><el-input type="textarea" :rows="10" v-model="articleDetail.content" disabled></el-input></el-card><el-divider/><div><p><strong><el-icon><UserFilled/></el-icon>您關注的用戶也收藏過這篇文章:</strong></p><el-button v-for="(user, index) in articleDetail.favoriteList">{{ user.realName }}</el-button></div><el-divider/><div style="text-align: center"><el-button type="danger" @click="detailDialogVisible = false"><el-icon><Close/></el-icon>關閉窗口</el-button></div></el-dialog></template>

2)script:

import {ElMessage} from "element-plus";
import {reactive, ref} from "vue";
import {useRouter} from "vue-router";
import {Close, Timer, User} from "@element-plus/icons-vue";
const router = useRouter();   // 創建路由實例//****************************************搜索表單********************************************//
// 搜索條件
const searchForm = reactive({title: ''
});// 搜索方法
const search = () => {ElMessage.success(`搜索成功${searchForm.title}`);
};//****************************************文章列表********************************************//
const articles = [{id: '1',title: '如何成為一名Java工程師?',publishUser: '小灰',publishDate: '2030-01-01 10:00:00',content: '文章內容'},{id: '2',title: '如何成為一名Java工程師?',publishUser: '小藍',publishDate: '2030-01-01 10:00:00',content: '文章內容'}
];//****************************************分頁組件********************************************//
// 當前頁
const currentPage = ref(1)
// 頁大小
const pageSize = ref(10)// 當頁大小發生改變時執行
const handleSizeChange = (val) => {ElMessage.success(`每頁顯示:${val}`)
}// 當當前頁發生改變時執行
const handleCurrentChange = (val) => {ElMessage.success(`當前頁碼:${val}`)
}//****************************************文章詳情********************************************//
// 查詢文章詳情
const showDetail = (id) => {ElMessage.success(`顯示文章詳情:${id}`);detailDialogVisible.value = true;
}// 文章詳情彈窗是否顯示
const detailDialogVisible = ref(false);// 文章詳情
const articleDetail = reactive({id: 1,title: '如何成為一名Java工程師?',content: '如何成為一名Java工程師如何成為一名Java工程師如何成為一名Java工程師如何成為一名Java工程師',publishUser: '小灰',publishDate: '2030-01-01 10:00:00',collectors: ['小灰', '小藍'],favoriteCount: 89,browseCount: 1246,favoriteList: [{id: "1", realName: '小灰'},{id: "2", realName: '小藍'},{id: "3", realName: '小綠'},]
});// 添加/取消收藏
const addFavorite = (id) => {ElMessage.success(`收藏成功:${articleDetail.id}`);
};

3.7 部門模塊

效果如下:

1)布局代碼:

<template><!-- *************************************************條件搜索************************************************* --><h3>全部部門</h3><el-form inline><el-form-item><el-input v-model="searchText" placeholder="請輸入關鍵字搜索"></el-input></el-form-item></el-form><!-- *************************************************樹形組件************************************************* --><el-treeref="treeRef":data="data":default-expand-all="true":filter-node-method="filterNode"></el-tree></template>

2)script:

<script lang="ts" setup>      // 注意是ts語法import {ref, watch} from 'vue'
import type {TreeInstance} from 'element-plus'// 樹節點數據類型
interface Tree {[key: string]: any
}// 搜索框輸入值
const searchText = ref('')// 樹組件實例
const treeRef = ref<TreeInstance>()// 監聽searchText變化,使用Tree的filter方法過濾樹節點
watch(searchText, (val) => {treeRef.value!.filter(val)
})/*** :filter-node-method: 當調用了filter方法時,會觸發該方法,該方法的返回值決定是否顯示該節點* @param value: 調用filter方法時傳入的參數* @param data: 樹節點數據* @returns boolean: true表示顯示該節點,false表示不顯示該節點*/
const filterNode = (value: string, data: Tree) => {// 如果搜索框為空,則顯示所有節點if (!value) return true// 如果搜索框不為空,則根據節點的label屬性進行匹配return data.label.includes(value)
}// 樹組件數據
const data = [{id: 1,label: '研發部',children: [{id: 1,label: '小灰'},{id: 2,label: '小藍'},{id: 3,label: '小綠'}]},{id: 2,label: '財務部',children: [{id: 4,label: '小紅'},{id: 5,label: '小明'}]},{id: 3,label: '人事部',children: [{id: 6,label: '小龍'},{id: 7,label: '小軍'}]}
]</script>

3.8 會議模塊

3.8.1 會議列表

1)搜索表單

效果如下:

1)布局代碼:

<!-- *************************************************條件搜索************************************************* -->
<h3>會議列表</h3><el-row style="width: 100%;"><el-col :span="18"><el-form inline size="large"><el-form-item label="會議標題"><el-input v-model="searchForm.title" placeholder="請輸入搜索內容"></el-input></el-form-item><el-form-item label="會議狀態"><el-select v-model="searchForm.status" placeholder="請選擇" style="width: 160px"><el-option label="全部" :value="-1"></el-option><el-option label="未開始" :value="0"></el-option><el-option label="進行中" :value="1"></el-option><el-option label="已結束" :value="2"></el-option></el-select></el-form-item><el-form-item><el-button type="primary" @click="search">搜索</el-button></el-form-item></el-form></el-col><el-col :span="6" style="text-align: right;"><el-button type="primary" @click="addDialogVisible = true" size="large">發布會議</el-button></el-col></el-row>

2)script:

//****************************************搜索表單********************************************//
// 搜索條件
const searchForm = reactive({title: '',status: -1
});// 搜索方法
const search = () => {ElMessage.success(`搜索成功: ${searchForm.title} - ${searchForm.status}`);
};
2)表格組件

效果如下:

1)布局代碼:

<!-- *************************************************會議列表************************************************* -->
<div><el-card v-for="(meeting, index) in meetingList" :key="index" style="margin-bottom: 20px;"><el-link type="primary" :underline="false" @click="showDetail(meeting.id)">{{ meeting.title }}</el-link><p><el-text tag="strong"><el-icon><OfficeBuilding/></el-icon>部門:</el-text><el-tag>{{ meeting.deptName }}</el-tag></p><p><el-text tag="strong"><el-icon><Timer/></el-icon>發布時間:</el-text><el-tag type="success">{{ meeting.startTime }}</el-tag></p><el-text>{{ meeting.content }}</el-text></el-card></div>

2)script:

//****************************************會議列表********************************************//
const meetingList = [{id: '1',title: '關于《協同開發平臺》項目部分模塊升級的討論',deptName: '研發部',startTime: '2030-01-01 10:00:00',content: '功能升級如下:支持微信登錄、QQ登錄,支持通訊錄、群組、聊天室、會議室等功能。'},{id: '2',title: '關于《協同開發平臺》項目部分模塊升級的討論',deptName: '研發部',startTime: '2030-01-01 10:00:00',content: '功能升級如下:支持微信登錄、QQ登錄,支持通訊錄、群組、聊天室、會議室等功能。'}
];
3)分頁組件

效果如下:

1)布局代碼:

<!-- *************************************************分頁組件************************************************* -->
<div style="margin-top: 20px;display: flex;justify-content: center;"><el-paginationv-model:current-page="currentPage"v-model:page-size="pageSize":page-sizes="[3, 5, 10]"size="large"layout="total, sizes, prev, pager, next, jumper":total="400"@size-change="handleSizeChange"@current-change="handleCurrentChange"/>
</div>

2)script:

//****************************************分頁組件********************************************//
// 當前頁
const currentPage = ref(1)
// 頁大小
const pageSize = ref(10)// 當頁大小發生改變時執行
const handleSizeChange = (val) => {ElMessage.success(`每頁顯示:${val}`)
}// 當當前頁發生改變時執行
const handleCurrentChange = (val) => {ElMessage.success(`當前頁碼:${val}`)
}

3.8.2 發布會議

1)發布會議對話框

當點擊“發布會議”按鈕時,應該彈出對話框。

1)布局代碼:

<!-- *************************************************發布會議彈窗************************************************* -->
<el-dialog title="發布會議" v-model="addDialogVisible" style="width: 60%;"><el-divider/><el-form ref="form" :model="meetingForm" label-width="80px" size="large"><el-form-item label="文章標題"><el-input v-model="meetingForm.title" placeholder="請輸入文章標題"></el-input></el-form-item><el-row><el-col :span="12"><el-form-item label="部門"><el-select v-model="meetingForm.deptId" placeholder="請選擇"><el-option label="研發部" :value="1"></el-option><el-option label="產品部" :value="2"></el-option><el-option label="測試部" :value="3"></el-option></el-select></el-form-item></el-col><el-col :span="12"><el-form-item label="抄送人"><el-select v-model="meetingForm.makeUser" placeholder="請選擇" multiple><el-option label="小灰" value="1"></el-option><el-option label="小藍" value="2"></el-option><el-option label="小綠" value="3"></el-option></el-select></el-form-item></el-col></el-row><el-row><el-col :span="12"><el-form-item label="開始時間"><el-date-picker v-model="meetingForm.startTime" type="datetime"placeholder="請選擇開始時間"></el-date-picker></el-form-item></el-col><el-col :span="12"><el-form-item label="結束時間"><el-date-picker v-model="meetingForm.endTime" type="datetime" placeholder="請選擇結束時間"></el-date-picker></el-form-item></el-col></el-row><el-form-item label="文章內容"><el-input type="textarea" :rows="8" v-model="meetingForm.content" placeholder="請輸入文章內容"></el-input></el-form-item></el-form><el-divider/><div slot="footer" class="dialog-footer"><el-button type="primary" @click="add">確 定</el-button><el-button @click="addDialogVisible = false">取 消</el-button></div></el-dialog>

2)script:

//****************************************發布會議********************************************//// 新增會議彈窗是否顯示
const addDialogVisible = ref(false);// 會議對象
const meetingForm = reactive({id: '',title: '',content: '',deptId: 1,startTime: '',endTime: '',makeUser: []
});// 新增會議方法
const add = () => {ElMessage.success(`新增會議成功:${JSON.stringify(meetingForm)}`);addDialogVisible.value = false;console.log(meetingForm);
};
2)綁定事件

給“發布會議”按鈕綁定事件:

<el-button type="primary" @click="addDialogVisible = true" size="large">發布會議</el-button>

3.8.2 會議詳情對話框

1)會議詳情對話框

當點擊某個會議標題時,查詢會議詳情。

效果如下:

1)布局代碼:

<!-- *************************************************會議詳情彈窗************************************************* -->
<el-dialog title="會議詳情" v-model="detailDialogVisible" width="60%" top="2vh"><div style="position: relative"><h2 style="text-align: center">{{ meetingDetail.title }}</h2><el-button style="position: absolute;top:0;right: 10px;" type="success" @click="joinMeeting(meetingDetail.id)">參加會議</el-button></div><el-divider/><el-card><el-row><el-col :span="3"><strong><el-icon><OfficeBuilding/></el-icon>部門:</strong></el-col><el-col :span="12">{{ meetingDetail.deptName }}</el-col></el-row><el-divider style="width:30%;margin: 10px 0"/><el-row><el-col :span="3"><strong><el-icon><Timer/></el-icon>發布時間:</strong></el-col><el-col :span="12">{{ meetingDetail.publishDate }}</el-col></el-row><el-divider style="width:30%;margin: 10px 0"/><el-row><el-col :span="3"><strong><el-icon><CirclePlusFilled/></el-icon>開始時間:</strong></el-col><el-col :span="12">{{ meetingDetail.startTime }}</el-col></el-row><el-divider style="width:30%;margin: 10px 0"/><el-row><el-col :span="3"><strong><el-icon><RemoveFilled/></el-icon>結束時間:</strong></el-col><el-col :span="12">{{ meetingDetail.endTime }}</el-col></el-row><el-divider style="width:30%;margin: 10px 0"/><el-row><el-col :span="3"><strong><el-icon><Promotion/></el-icon>應到人數:</strong></el-col><el-col :span="3"><el-tag type="primary"> {{ meetingDetail.joinCount }}</el-tag></el-col><el-col :span="3"><strong><el-icon><SuccessFilled/></el-icon>實到人數:</strong></el-col><el-col :span="3"><el-tag type="success"> {{ meetingDetail.realCount }}</el-tag></el-col><el-col :span="3"><strong><el-icon><RemoveFilled/></el-icon>未到人數:</strong></el-col><el-col :span="3"><el-tag type="danger"> {{ meetingDetail.noCount }}</el-tag></el-col></el-row><el-divider style="width:80%;margin: 10px 0"/><p><strong><el-icon><Document/></el-icon>會議內容:</strong></p><el-input type="textarea" :rows="10" v-model="meetingDetail.content" disabled></el-input></el-card><el-divider/><div><p><strong><el-icon><UserFilled/></el-icon>以下用戶需要參加本次會議:</strong></p><el-button :type="user.joinMeeting ? 'primary' : 'danger'" disabledv-for="(user, index) in meetingDetail.makeUser">{{ user.realName }}</el-button></div><el-divider/><div style="text-align: center"><el-button type="danger" @click="detailDialogVisible = false"><el-icon><Close/></el-icon>關閉窗口</el-button></div></el-dialog>

2)script:

//****************************************會議詳情********************************************//
// 會議詳情彈窗是否顯示
const detailDialogVisible = ref(false);// 查詢會議詳情
const showDetail = (id) => {ElMessage.success(`顯示會議詳情:${id}`);detailDialogVisible.value = true;
}// 會議詳情
const meetingDetail = reactive({id: 1,title: '關于《協同開發平臺》項目部分模塊升級的討論',content: '功能升級如下:支持微信登錄、QQ登錄,支持通訊錄、群組、聊天室、會議室等功能。',deptName: '研發部',publishDate: '2030-01-01 10:00:00',startTime: '2030-01-01 10:00:00',endTime: '2050-01-01 10:00:00',joinCount: 4,realCount: 2,noCount: 2,makeUser: [{id: "1", realName: '小灰', joinMeeting: true},{id: "2", realName: '小藍', joinMeeting: false},{id: "3", realName: '小綠', joinMeeting: true},{id: "4", realName: '小紅', joinMeeting: false},]
});// 添加/取消收藏
const joinMeeting = (id) => {ElMessage.success(`參加成功:${meetingDetail.id}`);
};

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/80174.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/80174.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/80174.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Webug4.0靶場通關筆記22- 第27關文件包含

目錄 一、文件包含 1、原理分析 2、文件包含函數 &#xff08;1&#xff09;include( ) &#xff08;2&#xff09;include_once( ) &#xff08;3&#xff09;require( ) &#xff08;4&#xff09;require_once( ) 二、第27關滲透實戰 1、打開靶場 2、源碼分析 3、…

〖 Linux 〗解決 VS Code 遠程連接服務器的常見問題

文章目錄 解決 VS Code 遠程連接服務器的斷開問題VS Code Remote-SSH一直彈出輸入密碼的問題VsCode C 語法檢測失效不標紅色波浪線 解決辦法卸載擴展方式&#xff1a; 解決vscode C智能提示緩慢 解決 VS Code 遠程連接服務器的斷開問題 解決 vscode 卡頓&#xff0c;卡死&…

ERC-20與ERC-721:區塊鏈代幣標準的雙星解析

一、代幣標準的誕生背景 在以太坊生態中&#xff0c;代幣標準是構建去中心化應用&#xff08;DApps&#xff09;的基石。ERC-20與ERC-721分別代表同質化與非同質化代幣的兩大核心標準&#xff0c;前者支撐著90%以上的加密資產流通&#xff0c;后者則開啟了數字資產唯一性的新時…

C++入門小館 :多態

嘿&#xff0c;各位技術潮人&#xff01;好久不見甚是想念。生活就像一場奇妙冒險&#xff0c;而編程就是那把超酷的萬能鑰匙。此刻&#xff0c;陽光灑在鍵盤上&#xff0c;靈感在指尖跳躍&#xff0c;讓我們拋開一切束縛&#xff0c;給平淡日子加點料&#xff0c;注入滿滿的pa…

【NextPilot日志移植】整體功能概要

整體日志系統的實現功能 該日志系統主要實現了飛行日志的記錄功能&#xff0c;支持多種日志記錄模式&#xff0c;可將日志存儲到文件或通過 MAVLink 協議傳輸&#xff0c;同時具備日志加密、空間管理、事件記錄等功能。具體如下&#xff1a; 日志記錄模式&#xff1a;支持按武…

數字化轉型:概念性名詞淺談(第二十五講)

大家好&#xff0c;今天接著介紹數字化轉型的概念性名詞系列。 &#xff08;1&#xff09;SOP(標準作業程序) 標準作業程序&#xff08;Standard Operating Procedure, SOPs&#xff09;是在有限時間與資源內&#xff0c;為了執行復雜的日常事務所設計的內部程序。從管理學的…

交叉編譯 opencv-4.10

編譯說明 opencv 下包含很多模塊&#xff0c;各個模塊的作用可以參考Opencv—模塊概覽. 嵌入式考慮有限存儲等因素會對模塊進行裁剪&#xff0c;我這里主要保留圖像拼接&#xff08;stitching&#xff09;圖片編解碼&#xff08;imgcodecs&#xff09;與特征點匹配&#xff08…

Python cv2對象檢測與跟蹤:從基礎到進階實戰

在計算機視覺領域&#xff0c;對象檢測&#xff08;定位目標位置&#xff09;與對象跟蹤&#xff08;持續追蹤目標運動&#xff09;是視頻分析、自動駕駛、智能監控等應用的核心技術。本文將結合OpenCV的cv2庫&#xff0c;系統講解其原理與Python實現方法。 一、對象檢測 vs 對…

亞馬遜推出新型倉儲機器人 Vulcan:具備“觸覺”但不會取代人類工人

每周跟蹤AI熱點新聞動向和震撼發展 想要探索生成式人工智能的前沿進展嗎&#xff1f;訂閱我們的簡報&#xff0c;深入解析最新的技術突破、實際應用案例和未來的趨勢。與全球數同行一同&#xff0c;從行業內部的深度分析和實用指南中受益。不要錯過這個機會&#xff0c;成為AI領…

緩存套餐-03.功能測試

一.功能測試 點擊小程序&#xff0c;就會觸發根據分類id查詢套餐方法&#xff0c;根據分類id查詢套餐。 第一次查詢&#xff0c;redis中沒有數據&#xff0c;就會發sql進行sql數據庫查詢。 redis當中就有了對應的緩存。 再次點擊&#xff0c;發現sql根本沒有執行&#xff0c;…

WebFlux與HttpStreamable關系解析

1-Streamable 1-WebFlux與HttpStreamable關系解析2-MCP協議Streamable HTTP 2-參考網址 MCP協議Streamable HTTPMCP協議重大升級&#xff0c;Spring AI Alibaba聯合Higress發布業界首個Streamable HTTP實現方案 3-WebFlux與HttpStreamable關系解析 WebFlux 和 HttpStreamabl…

順豐科技:從 Presto 到 Doris 湖倉構架升級,提速 3 倍,降本 48%

導讀&#xff1a;順豐科技引入 Doris 替換 Presto&#xff0c;在內部可視化數據自助分析工具豐景臺場景廣泛應用。目前&#xff0c;順豐臨時查詢業務、豐景臺報表業務的 Presto 場景已經 100% 切換到 Doris 集群中&#xff0c;日均查詢量 100W。并實現 P95 性能提升近 3 倍&…

如何在Jmeter中調用C程序?

在JMeter中調用C語言程序可以通過以下幾種方式實現&#xff1a; 方法一&#xff1a;使用OS Process Sampler JMeter的“OS Process Sampler”可以用來調用外部程序&#xff0c;包括C語言編寫的可執行文件。 步驟&#xff1a; 準備C語言程序&#xff1a; 編寫C語言代碼并編譯…

python 中的單例

在 Python 里&#xff0c;單例模式指的是一個類僅有一個實例&#xff0c;并且提供一個全局訪問點來獲取該實例。下面為你介紹幾種實現單例模式的常見方法。 1. 使用模塊 在 Python 里&#xff0c;模塊天然就是單例模式。當模塊被導入時&#xff0c;Python 會對其進行一次加載…

Linux58 ssh服務配置 jumpserver 測試雙網卡 為何不能ping通ip地址

判斷為NAT模式網卡 能ping 通外網 ens34為僅主機模式網卡 [rootlocalhost network-scripts]# ip route show default default via 10.1.1.254 dev ens33 proto static metric 100 10.0.0.0/8 dev ens33 proto kernel scope link src 10.1.1.37 metric 100 11.0.0.0/8 dev…

web 自動化之 selenium+webdriver 環境搭建及原理講解

文章目錄 一、web 自動化測試學習說明二、什么 web 自動化測試三、selenium 簡介四、web自動化測試環境搭建五、web 自動化測試第一個腳本六、selenium 原理及源碼講解 一、web 自動化測試學習說明 進階 web 自動化測試學習&#xff1a;掌握 python 編程基礎 二、什么 web 自…

Linux 網絡命名空間:從內核資源管理到容器網絡隔離

1. 網絡命名空間是什么? 網絡命名空間(Network Namespace) 是 Linux 內核提供的一種網絡資源隔離機制,用于為進程或容器創建完全獨立的網絡環境。它并非物理或虛擬的網絡接口(如網卡、veth pair 等),而是一個虛擬容器,包含以下資源的獨立實例: 網絡接口(物理或虛擬)…

SQL知識點總結

總結的知識點主要來源于前段時間在牛客刷SQL題目中遇到的錯誤 目錄 1.WHERE字句不能與高級函數連用 2.去重——distinct 3.不等于某個值 4.查多個范圍內的值 5. 升/降序排序 6.占位符 7.統計某類別總數計算平均值 8.合并查詢——UNION &#xff08;ALL&#xff09; 9…

【軟考-高級】【信息系統項目管理師】【論文基礎】采購管理過程輸入輸出及工具技術的使用方法

采購管理概念 項目采購管理包括從項目團隊外部采購或獲取所需產品、服務或成果的各個過程。項目采購管理包括編制和管理協議所需的管理和控制過程&#xff0c;例如合同、訂購單、協議備忘錄&#xff08;MOA&#xff09;和服務水平協議&#xff08;SLA&#xff09;。 采購管理…

C++ 手寫一個內存池

內存池是一種內存管理技術&#xff0c;它預先分配一大塊內存&#xff0c;之后將其按需分割成多個小塊供程序使用。下面將詳細闡述它的好處以及適用場景。 內存池的好處 減少內存碎片&#xff1a;在動態內存分配時&#xff0c;頻繁地分配和釋放不同大小的內存塊&#xff0c;會…