平台项目列表页实现(二)

一、顶部盒子设计

在这里插入图片描述

1. 顶部盒子包含项目列表和添加项目、退出登录2个按钮

在这里插入图片描述

<template>
    <!-- 项目列表页面 -->
    <div class="pros_box">
        <!-- 顶部的盒子 -->
        <div class="top_box">
            <span>项目列表</span>
            <el-button icon="User" color="#00aa7f">退出登录</el-button>
            <el-button icon="Plus" color="#00aa7f">添加项目</el-button>
        </div
    </div>
</template>

<script>

</script>

<style scoped>
/* 顶部内容 */
    .top_box{
        border-bottom:solid 5px #00aa7f;
        height: 50px;  设置高度
        font:bold 20px/40px '微软雅黑';
        color: #00aa7f; 设置背景颜色
        margin: 20px auto; 
    }
    
    /* 大盒子 */
    .pros_box{
        margin: 30px auto;
        max-width: 1400px;
    }
    /* 顶部按钮 */
    .top_box .el-button{
        float:right; 右浮动
        margin: 10px;
    }
</style>

二、项目列表盒子设计

在这里插入图片描述
在这里插入图片描述

项目列表页面(整个页面的大盒子)包含显示项目列表的区域(显示所有项目的盒子)包含单个项目(单个项目的盒子)包含图标、项目名称、负责人、2个按钮,共4个盒子

<template>
    <!-- 项目列表页面 -->
    <div class="pros_box">
        <!-- 顶部的盒子 -->
        <div class="top_box">
            <span>项目列表</span>
            <el-button icon="User" color="#00aa7f">退出登录</el-button>
            <el-button icon="Plus" color="#00aa7f">添加项目</el-button>
        </div>

        <!-- 显示项目列表的区域 -->
        <div class="pro_list">
            <!-- 单个项目 -->
            <el-card class="pro">
                <!-- 图标 -->
                <div class="pro_icon">
                    <el-icon><Platform /></el-icon>
                </div>
                <!-- 项目名称 -->
                <div class="pro_name">
                    演示项目
                </div>
                <!-- 负责人 -->
                <div class="leader">
                    负责人:kobe
                </div>
                <div class="btns">
                    <el-button size="small" icon="Edit" style="float:left;" color="#efefef">编辑</el-button>
                    <el-button size="small" icon="Delete" style="float:right;" color="#efefef">删除</el-button>
                </div>
            </el-card>

        </div>

    </div>
</template>

<script>

</script>

<style scoped>
/* 顶部内容 */
    .top_box{

        border-bottom:solid 5px #00aa7f;
        height: 50px;
        /* 设置字体加粗 宽度和高度  */
        font:bold 20px/40px '微软雅黑';
        /* 设置颜色 */
        color: #00aa7f;
        margin: 20px auto;
    }
    

    /* 大盒子 */
    .pros_box{
        margin: 30px auto;
        /* 设置最大宽度 */
        max-width: 1400px;
    }
    /* 顶部按钮 */
    .top_box .el-button{
        /* 右浮动 */
        float:right;
        margin: 10px;
    }
    /* 项目列表样式 */
    .pro{
        width:200px;
        height: 250px;
        float: left;
        margin: 10px;
    }
    /* 项目中图标的样式 */
    .pro .pro_icon{
        width: 60px;
        height: 60px;
        border-radius: 30px;  
        /* 背景颜色 */
        background: #e1ffed;
        color: #00aa7f;
        font: normal 30px/60px '微软雅黑';
        /* 居中 */
        text-align: center;
        margin: 0 auto;
    }
    /* 项目名称的样式 */
    .pro .pro_name{
        text-align: center;
        margin-top: 20px;
        font: bold 18px/20px '微软雅黑';
    }
    /* 负责人 */
    .pro .leader{
        text-align: center;
        color: rgb(55, 28, 206);
        /* 设置:字体/行高 */
        font: normal 15px/40px '微软雅黑'; 
        /* margin-bottom: 10px;  */
    }

    /* 按钮区域 */
    .pro .btns{
        margin-top: 50px;
        text-align: center;
    }
 
    	
</style>

三、添加项目盒子设计

在这里插入图片描述

<template>
	......
	......
	 <!-- 添加项目的盒子 -->
     <el-card class="pro">
         <div class="add_box">
             <el-icon :size="50" color="green"><Plus /></el-icon>
         </div>
     </el-card>
</template>


<style scoped>
	......
	/* 添加项目 */
    .pro .add_box{
        /* 水平居中 */
        text-align: center; 
        /* 高度 */
        /* height: 250px; */
        /* 行高 */
        line-height: 200px;
    }
    ......
</style>

四、退出登录功能实现

<el-button @click="logout"  icon='User' color='#00aa7f'>退出登录</el-button>
<script>
	export default{
		data(){
			return{
				
			}
		},
		methods:{
			// 退出登录
			logout(){
				//清除token和用户名
				window.sessionStorage.removeItem('token')
				window.sessionStorage.removeItem('username')
				//跳转到登录页面
				this.$router.push({name:'login'})
				
			}
		}
	}
</script>

五、路由导航守卫实现

添加路由导航守卫,控制前端页面访问的权限

router.beforeEach(async (to, from) => {
	// 获取sessionStorage是否存在token,如果存在token视为已经登录
	const isAuthenticated = window.sessionStorage.getItem('token')
    if (
	   // 检查用户是否已登录
	   !isAuthenticated &&
	   // ❗️ 避免无限重定向
	   to.name !== 'login'
	 ) {
	   // 将用户重定向到登录页面
	   return { name: 'login' }
	 }
    })
 

六、展示项目信息

<script>
	export default{
		data(){
			return{
				//项目列表信息
				projectList:[
					
				]
			}
		},
		methods:{
			...
			...
			// 通过接口获取后端所有的项目
			async getAllProject(){
				const response= await this.$api.getAllProjects()
				if(response.status===200){
					console.log(response.data)
					// 将获取到的项目信息保存到data中
					this.projectList=response.data
				}
			}
		},
		// 钩子函数,最先执行的方法
		created(){
			this.getAllProject()
		}
	}
</script>
<!-- 显示项目列表的区域 -->
		<div class="pro_list">
			<!-- 单个项目显示在一个el-card -->
			<el-card class="pro" v-for="pro in projectList" :key='pro.id'>
			  <!-- 图标 -->
			  <div class="pro_icon">
				  <el-icon><Platform /></el-icon>
			  </div>
			  <!-- 项目名称 -->
			  <div class="pro_name">
				  {{pro.name}}
			  </div>
			  <!-- 项目负责人 -->
			  <div class="pro_leader">
				  {{pro.leader}}
			  </div>
			  <!-- 按钮 -->
			  <div class="btns">
				  <el-button  color="#d9d9d9" class="edit" size="small" icon="Edit">编辑</el-button>
				  <el-button color="#F5F5DC" class="del" size="small" icon="Delete">删除</el-button>
			  </div>
 
			</el-card>
			
			<!-- 添加项目的空盒子-->
			<el-card class="pro">
			  <!-- 图标 -->
			  <div class="add_pro">
				  <el-icon :size=70>
					  <Plus/>
				  </el-icon>
			  </div>
			 
			</el-card>
			
		</div>

七、bug修复

在这里插入图片描述

1、当项目名称太长或者项目负责人太长,需要一行展示,当超过8个字…展示

 <!-- 项目名称 -->
  <div class="pro_name">
	<span v-if="pro.name.length<8">{{pro.name}}</span>
	<el-tooltip v-else class="item" effect="dark" v-bind:content=pro.name placement="top-start">
			{{pro.name.slice(0,8)}}...
	</el-tooltip>
  </div>
  
  <!-- 项目负责人 -->
  <div class="pro_leader">
	  <span v-if="pro.leader.length<8">{{pro.leader}}</span>
	  <el-tooltip v-else class="item" effect="dark" v-bind:content=pro.leader placement="top-start">
	  		{{pro.leader.slice(0,8)}}...
	  </el-tooltip>
  </div>

八、删除单个项目

index.js

export default{
	// 登录接口
	login(params){
		return http.post('/login/',params)
	},
	// ---------------------------项目操作的api---------------------------
	// 获取项目列表
	getAllProjects(){
		return http.get('/projects/')
	},
	// 删除项目的接口
	delProject(id){
		return http.delete(`/projects/${id}/`)
	}
}
<div class="btns">
	  <el-button  color="#d9d9d9" class="edit" size="small" icon="Edit">编辑</el-button>
	  <el-button color="#F5F5DC" class="del" size="small" icon="Delete" @click="clickDelete(pro.id)">删除</el-button>
  </div>
<script>
	import { ElMessage, ElMessageBox } from 'element-plus'
	
	export default{
		data(){
			return{
				//项目列表信息
				projectList:[
					
				]
			}
		},
		methods:{
			...
			...
				
			// 通过接口获取后端所有的项目
			async getAllProject(){
				const response= await this.$api.getAllProjects()
				if(response.status===200){
					console.log(response.data)
					// 将获取到的项目信息保存到data中
					this.projectList=response.data
				}
			},
			// 调用接口删除项目
			async deletePro(proId){
				//发送接口请求
				const response = await this.$api.delProject(proId)
				if(response.status===204){
					//更新页面的数据
					this.getAllProject()
					//提示删除成功
					this.$message({
					  type: 'success',
					  message: '删除成功!'
					})
				}
			},
			
			// 点击删除项目
			clickDelete(id){
				this.$confirm('此操作不可恢复,确定要删除吗?', {
				          confirmButtonText: '确定',
				          cancelButtonText: '取消',
				          type: 'warning'
				        }).then(() => {
							// 调用删除的接口
							this.deletePro(id)

						  // 取消操作 -->
				        }).catch(() => {
				          this.$message({
				            type: 'info',
				            message: '已取消删除'
				          });          
				        });
			}
		},
		// 钩子函数,最先执行的方法
		created(){
			this.getAllProject()
		}
	}
</script>

九、添加项目功能

index.js

export default{
	// 登录接口
	login(params){
		return http.post('/login/',params)
	},
	// ---------------------------项目操作的api---------------------------
	// 获取项目列表
	getAllProjects(){
		return http.get('/projects/')
	},
	// 删除项目的接口
	delProject(id){
		return http.delete(`/projects/${id}/`)
	},
	//添加项目的接口
	createProject(params){
		return http.post('/projects/',params)
	}
	
}
<!-- 顶部盒子 -->
<div class="top_box">
	<span>项目列表</span>
	<el-button @click="logout"  icon='User' color='#00aa7f'>退出登录</el-button>
	<el-button @click="addDlg=true" icon='Plus' color='#00aa7f'>添加项目</el-button>
</div>

<!-- 添加项目的空盒子-->
<el-card class="pro">
  <!-- 图标 -->
  <div class="add_pro" @click="addDlg=true">
	  <el-icon :size=70>
		  <Plus/>
	  </el-icon>
  </div>
 
</el-card>



<!-- 添加项目的弹框 -->
<el-dialog v-model="addDlg" title="添加项目" >
  <el-form :model="form">
    <el-form-item label="项目名称">
      <el-input v-model="addForm.name"></el-input>
    </el-form-item>
	<el-form-item label="负责人">
	  <el-input v-model="addForm.leader"></el-input>
	</el-form-item>
  </el-form>

  <div class="dialog-footer">
    <el-button @click="addDlg = false">取 消</el-button>
    <el-button type="primary" @click="addPro">确 定</el-button>
  </div>
</el-dialog>
<script>
	import { ElMessage, ElMessageBox } from 'element-plus'
	
	export default{
		data(){
			return{
				//项目列表信息
				projectList:[
					
				],
				// 添加项目的弹框是否显示
				addDlg:false,
				// 向表单中输入的文字
				addForm:{
					name:"",
					leader:""
				}
			}
		},
		methods:{
			...
			...
			...
			// 添加项目
			async addPro(){
				// 发送请求
				const response=await this.$api.createProject(this.addForm)
				if(response.status===201){
					//更新页面的数据
					this.getAllProject()
					// 关闭窗口
					this.addDlg=false
					this.$message({
					  type: 'success',
					  message: '添加成功!'
					})
				}
			}
			
		},
		// 钩子函数,最先执行的方法
		created(){
			this.getAllProject()
		}
	}
</script>

十、编辑和添加使用同一个弹框

title:不写死
在这里插入图片描述
在data中设置dlgTitle为弹窗的标题
在这里插入图片描述
接着在显示title的地方,设置数据绑定
在这里插入图片描述
给编辑按钮添加一个事件clickEdit
在这里插入图片描述
在这里插入图片描述
修改点击添加的方法clickAdd
在这里插入图片描述
在这里插入图片描述

十一、编辑项目

index.js


export default{
	// 登录接口
	login(params){
		return http.post('/login/',params)
	},
	// ---------------------------项目操作的api---------------------------
	// 获取项目列表
	getAllProjects(){
		return http.get('/projects/')
	},
	// 删除项目的接口
	delProject(id){
		return http.delete(`/projects/${id}/`)
	},
	//添加项目的接口
	createProject(params){
		return http.post('/projects/',params)
	},
	// 修改项目
	updateProject(id,params){
		return http.patch(`/projects/${id}/`,params)
	}
	
}

根据dlgTitle发送不同的接口
加粗样式
在这里插入图片描述
id怎么传?
this.addForm={…pro}:将项目信息赋值给addForm

在这里插入图片描述

十二、总体实现代码

<template>
	<!-- 项目列表页面 -->
	<div class="pros_box">
		<!-- 顶部盒子 -->
		<div class="top_box">
			<span>项目列表</span>
			<el-button @click="logout"  icon='User' color='#00aa7f'>退出登录</el-button>
			<el-button @click="clickAdd" icon='Plus' color='#00aa7f'>添加项目</el-button>
		</div>
		
		
		<!-- 显示项目列表的区域 -->
		<div class="pro_list">
			<!-- 单个项目显示在一个el-card -->
			<el-card class="pro" v-for="pro in projectList" :key='pro.id'>
			  
			  <div style="cursor: pointer;" @click="selectPro(pro)">
				  <!-- 图标 -->
				  <div class="pro_icon">
				  				  <el-icon><Platform /></el-icon>
				  </div>
				  <!-- 项目名称 -->
				  <div class="pro_name">
				  				<span v-if="pro.name.length<8">{{pro.name}}</span>
				  				<el-tooltip v-else class="item" effect="dark" v-bind:content=pro.name placement="top-start">
				  						{{pro.name.slice(0,8)}}...
				  				</el-tooltip>
				  </div>
				  
				  <!-- 项目负责人 -->
				  <div class="pro_leader">
				  				  <span v-if="pro.leader.length<8">{{pro.leader}}</span>
				  				  <el-tooltip v-else class="item" effect="dark" v-bind:content=pro.leader placement="top-start">
				  				  		{{pro.leader.slice(0,8)}}...
				  				  </el-tooltip>
				  </div>
			  </div>
			  
			  <!-- 按钮 -->
			  <div class="btns">
				  <el-button @click="clickEdit(pro)"  color="#d9d9d9" class="edit" size="small" icon="Edit">编辑</el-button>
				  <el-button color="#F5F5DC" class="del" size="small" icon="Delete" @click="clickDelete(pro.id)">删除</el-button>
			  </div>
 
			</el-card>
			
			<!-- 添加项目的空盒子-->
			<el-card class="pro">
			  <!-- 图标 -->
			  <div class="add_pro" @click="clickAdd">
				  <el-icon :size=70>
					  <Plus/>
				  </el-icon>
			  </div>
			 
			</el-card>
			
		</div>
	</div>
	
	
	<!-- 添加项目的弹框 -->
	<!-- <el-dialog v-model="addDlg" title="添加项目" > -->
	  <!-- <el-form :model="form">
	    <el-form-item label="项目名称">
	      <el-input v-model="addForm.name"></el-input>
	    </el-form-item>
		<el-form-item label="负责人">
		  <el-input v-model="addForm.leader"></el-input>
		</el-form-item>
	  </el-form> -->

	  <!-- <div class="dialog-footer">
	    <el-button @click="addDlg = false">取 消</el-button> 
	    <el-button type="primary" @click="addPro">确 定</el-button>
	  </div>
	</el-dialog> -->
	
	<!-- 添加和编辑项目的弹窗 -->
	<el-dialog v-model="addDlg" :title="dlgTitle" >
	  <el-form :model="form">
	    <el-form-item label="项目名称">
	      <el-input v-model="addForm.name"></el-input>
	    </el-form-item>
		<el-form-item label="负责人">
		  <el-input v-model="addForm.leader"></el-input>
		</el-form-item>
	  </el-form>
	
	  <div class="dialog-footer">
	    <el-button @click="addDlg = false">取 消</el-button>
	    <!-- <el-button type="primary" @click="addPro">确 定</el-button> -->
		 <el-button v-if='(dlgTitle==="添加项目")' type="primary" @click="addPro">确 定</el-button>
		 <el-button v-else type="primary" @click="updatePro">提交修改</el-button>
		 
	  </div>
	</el-dialog>
	
</template>

<script>
	import { ElMessage, ElMessageBox } from 'element-plus'
	// 导入映射方法的函数mapActions
	import { mapActions } from 'pinia'
	import { userStore } from '../store/user.js'
	
	export default{
		data(){
			return{
				//项目列表信息
				projectList:[
					
				],
				// 添加项目的弹框是否显示
				addDlg:false,
				addForm:{
					name:"",
					leader:""
				},
				// 弹框的标题
				dlgTitle:"添加项目"
			}
		},
		methods:{
			// 退出登录
			// logout(){
			// 	//清除token和用户名
			// 	window.sessionStorage.removeItem('token')
			// 	window.sessionStorage.removeItem('username')
			// 	//跳转到登录页面
			// 	this.$router.push({name:'login'})	
			// },

			// 将全局定义的logout方法,映射为当前组件的logout方法
			...mapActions(userStore,['logout','savePro']),

			// 通过接口获取后端所有的项目
			async getAllProject(){
				const response= await this.$api.getAllProjects()
				if(response.status===200){
					console.log(response.data)
					// 将获取到的项目信息保存到data中
					this.projectList=response.data
				}
			},
			// 调用接口删除项目
			async deletePro(proId){
				//发送接口请求
				const response = await this.$api.delProject(proId)
				if(response.status===204){
					//更新页面的数据
					this.getAllProject()
					//提示删除成功
					this.$message({
					  type: 'success',
					  message: '删除成功!'
					})
				}
			},
			
			// 点击删除项目
			clickDelete(id){
				this.$confirm('此操作不可恢复,确定要删除吗?', {
				          confirmButtonText: '确定',
				          cancelButtonText: '取消',
				          type: 'warning'
				        }).then(() => {
							// 调用删除的接口
							this.deletePro(id)

						  // 取消操作 -->
				        }).catch(() => {
				          this.$message({
				            type: 'info',
				            message: '已取消删除'
				          });          
				        });
			},
			// 添加项目
			async addPro(){
				// 发送请求
				const response=await this.$api.createProject(this.addForm)
				if(response.status===201){
					//更新页面的数据
					this.getAllProject()
					// 关闭窗口
					this.addDlg=false
					this.$message({
					  type: 'success',
					  message: '添加成功!'
					})
				}
			},
			// 点击编辑执行 的方法
			clickEdit(pro){
				// 修改title
				this.dlgTitle='编辑项目'
				// 将项目信息赋值给addForm
				this.addForm={...pro}
				// 显示编辑框
				this.addDlg=true
			},
			// 点击添加项目
			clickAdd(){
				this.dlgTitle='添加项目'
				// 将项目信息addForm置空
				this.addForm={
					name:'',
					leader:''
				}
				// 展示弹窗
				this.addDlg=true
			},
			// 发送请求,修改编辑后的项目信息
			async updatePro(){
				const id=this.addForm.id
				const params={
					leader:this.addForm.leader,
					name:this.addForm.name
				}
				const response=await this.$api.updateProject(id,params)
				if(response.status===200){
					//更新页面的数据
					this.getAllProject()
					// 提示
					this.$message({
					  type: 'success',
					  message: '修改成功!'
					})
				}
				// 关闭窗口
				this.addDlg=false
			},
			// 选择进入的项目
			selectPro(pro){
				this.$router.push({name:"home"})
				console.log(666)
				// 将项目信息保存到vue的全局数据存储仓库
				this.savePro(pro)
			}
			
		},
		// 钩子函数,最先执行的方法
		created(){
			
			this.getAllProject()
		}
	}
</script>

<style scoped>
	/* ----------------顶部样式--------------------- */
	/* 整体盒子 */
	.pros_box{
		max-width: 1480px;
		margin: 30px auto;
	}
	/* 顶部盒子 */
	.top_box{
		border-bottom: solid 5px green;
		height: 40px;
		font: bold 20px/40px '微软雅黑';
		color: #00aa7f;
		margin: 20px auto;
	}
	/* 顶部按钮 */
	.top_box .el-button{
		float: right;
		margin-left: 10px;
	}
	
	
	/* ------------------项目列表样式-------------------------- */
	
	.pro{
		width: 200px;
		height: 250px;
		margin: 20px;
		float: left;
	}
	/* 项目中图标样式 */
	.pro .pro_icon{
		width: 80px;
		height: 80px;
		border-radius: 40px;
		background: #e1ffed;
		color: #00aa7f;
		font: normal 30px/60px '微软雅黑';
		text-align: center;
		margin: 0 auto;
	}
	/* 项目名称的样式 */
	.pro .pro_name{
		text-align: center;
		margin-top: 20px;
		font: bold 18px/40px '微软雅黑';
	}
	/* 负责人的样式 */
	.pro .pro_leader{
		text-align: center;
		color: blue;
		font: normal 12px/20px '微软雅黑';	
	}
	/* 按钮区域的样式 */
	.pro .btns{
		margin-top: 30px;
	}
	.pro .btns .edit{
		float: left;
	}
	.pro .btns .del{
		float: right;
	}
	/*添加的盒子样式*/
	.pro .add_pro{
		text-align: center;
		height: 250px;
		line-height: 250px;
		color: #d3d4d3;
	}
	
	
	
	
	
</style>

index.js路由设置

const routes = [

  {
    path: '/',
    name: 'index',
    redirect:{name:"login"}
  },
  {
    path: '/user/login',
    name: 'login',
    component: () => import('../views/Login.vue')
  },
  {
    path: '/allProject',
    name: 'allProject',
    component: () => import('../views/AllProject.vue')
  },
  {
    path: '/home',
    name: 'home',
    component: () => import('../views/Home.vue')

  },
]

十三:鼠标放上指定的位置变成手,点击进入home页面

在这里插入图片描述
用大的div包起来

<!-- 单个项目显示在一个el-card -->
<el-card class="pro" v-for="pro in projectList" :key='pro.id'>
  
  <div style="cursor: pointer;" @click="selectPro(pro)">
	  <!-- 图标 -->
	  <div class="pro_icon">
	  				  <el-icon><Platform /></el-icon>
	  </div>
	  <!-- 项目名称 -->
	  <div class="pro_name">
	  				<span v-if="pro.name.length<8">{{pro.name}}</span>
	  				<el-tooltip v-else class="item" effect="dark" v-bind:content=pro.name placement="top-start">
	  						{{pro.name.slice(0,8)}}...
	  				</el-tooltip>
	  </div>
	  
	  <!-- 项目负责人 -->
	  <div class="pro_leader">
	  				  <span v-if="pro.leader.length<8">{{pro.leader}}</span>
	  				  <el-tooltip v-else class="item" effect="dark" v-bind:content=pro.leader placement="top-start">
	  				  		{{pro.leader.slice(0,8)}}...
	  				  </el-tooltip>
	  </div>
  </div>
  
  <!-- 按钮 -->
  <div class="btns">
	  <el-button @click="clickEdit(pro)"  color="#d9d9d9" class="edit" size="small" icon="Edit">编辑</el-button>
	  <el-button color="#F5F5DC" class="del" size="small" icon="Delete" @click="clickDelete(pro.id)">删除</el-button>
  </div>

</el-card>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

敲代码敲到头发茂密

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值