前言
对于多个项目的使用,可能需要进行项目切换管理,所以这里创建一个项目管理页面,登录成功后跳转这个页面,进行选择项目,再进入Home页面展示对应项目的内容。
一、实现效果图预览
二、页面内容
功能1、项目列表展示
这里使用element-plus的走马灯效果来实现
elment-plus走马灯效果
走马灯数据从接口获取。有多少项目,就展示多少
1、封装接口
2、在setup中请求后端数据,并赋值
javascript">//首先获取项目数据,接口定义
<script setup>import {ref} from 'vue'import http from '@/api/index'let proList = ref([])console.log('1::',proList.value)async function getProList(){const resposne = await http.pro.getProListApi()if(resposne.status == 200){console.log(resposne.data)proList.value = resposne.data}}getProList()</script>
3、通过循环展示
javascript"><template><el-carousel :interval="4000" type="card" height="200px" motion-blur><el-carousel-item v-for="item in proList" :key="item.id"><h3 text="2xl" justify="center">{{ item.name }}</h3></el-carousel-item></el-carousel>
</template>
剩下的内容就是把这些换成自己喜欢的图片,再加亿点点css样式美化一下页面。
功能2、创建新项目
在右上角新增一个按钮,点击展示添加项目的表单界面,填写内容,再提交(注意封装api接口),提交完成后,再刷新一下列表数据,展示到页面。
1. 界面增加按钮和添加弹窗
javascript"><el-button icon="CirclePlus" size="small" @click='showDlg'>添加项目</el-button>
...
<!-- 添加项目的弹框 -->
<el-dialog v-model="isDlgShow" title="添加项目"><el-form :model="fromData" label-width="80"><el-form-item label="项目名称"><el-input v-model="fromData.name" autocomplete="off" /></el-form-item><el-form-item label="负责人"><el-select v-model="fromData.leader" placeholder="选择负责人" ><el-option v-for="item in users" :key="item.id" :value="item.id" :label="item.nickname"></el-option></el-select></el-form-item></el-form><template #footer><span class="dialog-footer"><el-button @click="isDlgShow = false">取消</el-button><el-button type="primary" @click="creatPro">确认</el-button></span></template>
</el-dialog>
2. 添加函数功能
javascript">import {ref,reactive} from 'vue'
import {ElNotification} from 'element-plus'
import http from '@/api/index'
...
// ===================实现项目添加的功能=================
let isDlgShow = ref(false)
let users = ref([])
let fromData = reactive({name: "",leader: ""
})// 加载用户
async function getUserList(){const response = await http.user.getUserListApi()users.value = response.dataconsole.log(users.value)
}
// 显示添加窗口
function showDlg() {isDlgShow.value = true
}
// 发送请求添加项目
async function creatPro() {const response = await api.createProApi(fromData)if (response.status === 201) {// 弹出提示ElNotification({title: '项目创建成功',type: 'success',})// 关闭窗口isDlgShow.value = false// 刷新页面数据getProList()}
}
功能3、编辑和删除项目
再新增两个按钮,编辑和删除
javascript"> <!-- 按钮 -->
<div class="btn_box1"><el-button @click='clickEdit(item)' plain icon='Edit' type="primary" size="small"></el-button>
</div>
<div class="btn_box2"><el-button @click='clickDelete(item.id)' plain icon='Delete' type="danger" size="small"></el-button>
</div>
编辑
javascript">// api/module/ProjectApi.js
editProApi(pro_id,data){return request.patch(`/api/testPro/editProject/${pro_id}`,data)
}
javascript">// ProView.vue
// ===========实现项目修改的功能===================let isUpdateDlgShow = ref(false)let fromUpdateData = ref({name: "",leader: ""})// 点击编辑按钮时调用的方法function clickEdit(pro) {getUserList()isUpdateDlgShow.value = truefromUpdateData.value = { ...pro }// console.log("edit::",pro,{ ...pro })}// 发送请求修改项目信息async function updatePro() {let pro_id = fromUpdateData.value.idconst response = await http.pro.editProApi(pro_id, fromUpdateData.value)if (response.status === 200) {ElNotification({title: '项目修改成功',type: 'success',duration: 3000})// 关闭窗口isUpdateDlgShow.value = false// 刷新页面上的数据getProList()}}
删除
javascript">// ==============实现项目删除的功能=====================
function clickDelete(pro_id) {// 调用后端的接口进行删除ElMessageBox.confirm('删除操作不可恢复,请确认是否要删除该项目?','提示', {confirmButtonText: '确认',cancelButtonText: '取消',type: 'warning',}).then(async () => {// 调用接口进行删除const response = await http.pro.deleteProApi(pro_id)if (response.status === 204) {ElMessage({type: 'success',message: '已成功删除该项目',})// 刷新页面数据getProList()}}).catch(() => {ElMessage({type: 'info',message: '已取消删除操作',})})
}
功能4、进入Home页面
1.新建一个用于存储项目数据的pinia
javascript">// stores/moudel/ProStore.js
import {defineStore} from "pinia"
import http from '@/api/index'export const ProjectStore = defineStore('proStore',{state:() => {return {pro : {},}},persist:{enabled:true,strategies:[{key:'proInfo',storage:localStorage}]}
})
2. 选择项目点击跳转到home页
同时将选择的项目信息持久化储存到pinia中,以便后续使用
javascript"> // ===================点击进入选择的项目=================function enterProject(pro){console.log('enterclick')const proStore = ProjectStore()// 保存项目信息proStore.pro = prorouter.push('home')}
三、总结
- elment-plus走马灯数据展示
- el-select 下拉选择器
- ElNotification,ElMessage 消息反馈
- pinia持久化存储
部分页面代码
ProjectApi.js
javascript">import request from "@/api/request";//导出请求方法
export default {//获取项目列表getProListApi(){return request.get('/api/testPro/projects')},createProApi(data){return request.post('/api/testPro/projects',data)},editProApi(pro_id,data){return request.patch(`/api/testPro/editProject/${pro_id}`,data)},deleteProApi(pro_id){return request.delete(`/api/testPro/Projects/${pro_id}`)}}
ProView.vue
javascript"><template><div class="pro_page"><div class="pro_box"><div class="welcome"><span>欢迎使用自动化测试平台</span><el-button icon="CirclePlus" size="small" @click='showDlg'>添加项目</el-button></div><div class="pro_list"> <el-carousel :interval="4000" type="card" height="400px" motion-blur><el-carousel-item v-for="(item,index) in proList" :key="index"><div class="pro"><div @click='enterProject(item)'><!-- 图片 --><img src="@/assets/procard.jpg"><!-- 名称 --><div class="name">{{item.name}}</div></div><!-- 按钮 --><div class="btn_box1"><el-button @click='clickEdit(item)' plain icon='Edit' type="primary" size="small"></el-button></div><div class="btn_box2"><el-button @click='clickDelete(item.id)' plain icon='Delete' type="danger" size="small"></el-button></div></div></el-carousel-item></el-carousel></div><div class="iod">我觉得该写点什么,但是又不知道写点什么。</div><div class="iod">只是觉得这样看起来这里很空旷,随便写点东西占个位置</div></div><!-- 添加项目的弹框 --><el-dialog v-model="isDlgShow" title="添加项目"><el-form :model="fromData" label-width="80"><el-form-item label="项目名称"><el-input v-model="fromData.name" autocomplete="off" /></el-form-item><el-form-item label="负责人"><el-select v-model="fromData.leader" placeholder="选择负责人" ><el-option v-for="item in users" :key="item.id" :value="item.id" :label="item.nickname"></el-option></el-select></el-form-item></el-form><template #footer><span class="dialog-footer"><el-button @click="isDlgShow = false">取消</el-button><el-button type="primary" @click="creatPro">确认</el-button></span></template></el-dialog><!-- 修改项目的弹框 --><el-dialog v-model="isUpdateDlgShow" title="编辑项目"><el-form :model="fromUpdateData" label-width="80"><el-form-item label="项目名称"><el-input v-model="fromUpdateData.name" autocomplete="off" /></el-form-item><el-form-item label="负责人"><el-select v-model="fromUpdateData.leader" placeholder="选择负责人" ><el-option v-for="item in users" :key="item.id" :value="item.nickname" :label="item.nickname"></el-option></el-select></el-form-item></el-form><template #footer><span class="dialog-footer"><el-button @click="isUpdateDlgShow = false">取消</el-button><el-button type="primary" @click="updatePro">确认</el-button></span></template></el-dialog></div>
</template><script setup> import {ref,reactive} from 'vue'import {ElNotification,ElMessageBox,ElMessage} from 'element-plus'import http from '@/api/index'let proList = ref([])async function getProList(){const resposne = await http.pro.getProListApi()if(resposne.status == 200){// console.log(resposne.data)proList.value = resposne.data}}getProList()// ===================实现项目添加的功能=================let isDlgShow = ref(false)let users = ref([])let fromData = reactive({name: "",leader: ""})// 加载用户async function getUserList(){const response = await http.user.getUserListApi()users.value = response.data// console.log(users.value)}// 显示添加窗口function showDlg() {getUserList()isDlgShow.value = true}// 发送请求添加项目async function creatPro() {const response = await http.pro.createProApi(fromData)if (response.status === 201) {// 弹出提示ElNotification({title: '项目创建成功',type: 'success',duration: 3000})// 关闭窗口isDlgShow.value = false// 刷新页面数据getProList()}}// ===========实现项目修改的功能===================let isUpdateDlgShow = ref(false)let fromUpdateData = ref({name: "",leader: ""})// 点击编辑按钮时调用的方法function clickEdit(pro) {getUserList()isUpdateDlgShow.value = truefromUpdateData.value = { ...pro }// console.log("edit::",pro,{ ...pro })}// 发送请求修改项目信息async function updatePro() {let pro_id = fromUpdateData.value.idconst response = await http.pro.editProApi(pro_id, fromUpdateData.value)if (response.status === 200) {ElNotification({title: '项目修改成功',type: 'success',duration: 3000})// 关闭窗口isUpdateDlgShow.value = false// 刷新页面上的数据getProList()}}// ==============实现项目删除的功能=====================function clickDelete(pro_id) {// 调用后端的接口进行删除ElMessageBox.confirm('删除操作不可恢复,请确认是否要删除该项目?','提示', {confirmButtonText: '确认',cancelButtonText: '取消',type: 'warning',}).then(async () => {// 调用后端接口进行删除const response = await http.pro.deleteProApi(pro_id)if (response.status === 204) {ElMessage({type: 'success',message: '已成功删除该项目',})// 刷新页面数据getProList()}}).catch(() => {ElMessage({type: 'info',message: '已取消删除操作',})})}</script><style lang='scss' scoped>@use './pro.scss';
</style>
pro.scss
.pro_page{background-color: aliceblue;background-image:url('@/assets/bg.jpeg') ;height: 100vh;min-height: 700px;background-size: cover;.pro_box{height: 94%;width: 96%;background-color: rgba(255, 255, 255, 0.8);border-radius: 10px;position: relative;left: 2%;top: 3%;.el-button{position: absolute; // 设置绝对定位top: 10px;right: 10px;}.iod{margin-top: 20px;display: flex; // 使用 Flexbox 布局justify-content: center; // 水平居中align-items: center; // 垂直居中color: #2a2a2a;font-size: 24px;font-weight: bold;height: 80px;line-height: 80px;}// 顶部内容.welcome{display: flex; // 使用 Flexbox 布局justify-content: center; // 水平居中align-items: center; // 垂直居中color: #2a2a2a;font-size: 24px;font-weight: bold;height: 80px;line-height: 80px;}// 项目卡片.pro_list{.pro{position: relative;height: 400px;background: #00aaff;text-align: center;img{height: 400px; width: 100%; // 使图片宽度占满 .pro 容器object-fit: cover; // 保持图片比例并裁剪以填满容器}.name {position: absolute; // 设置绝对定位top: 50%;left: 50%;transform: translate(-50%, -50%); // 将文字居中color: #000; // 文字颜色font: bold 28px/80px '微软雅黑';background: rgba(0, 0, 0, 0.1); // 可选:背景色以提高可读性padding: 10px; // 可选:内边距border-radius: 5px; // 可选:圆角}.btn_box1{position: absolute; // 设置绝对定位left: 50%;bottom: 20%;transform: translate(-50%, -50%); // 将文字居中bottom: 55px;}.btn_box2{position: absolute; // 设置绝对定位left: 56%;bottom: 40px;transform: translate(-50%, -50%); // 将文字居中bottom: 55px;}}}}}