开始尝试从0写一个项目--前端(三)

avatar
作者
筋斗云
阅读量:0

器材管理板块

添加器材管理导航

src\views\home\Home.vue

src\router\index.js

src\views\equipment\Equipment.vue

<template>     <div>         hello!     </div>  </template>

测试

搜索导航+分页查询

src\views\equipment\Equipment.vue

<template>     <div>         <!-- 导航 -->         <el-form :inline="true" class="demo-form-inline">             <div style="float: left">                 <label style="margin-right: 5px">器材名称: </label>                 <el-input  v-model="name" placeholder="请输入器材名称" style="width: 40%" />                 <el-button type="primary" style="margin-left: 20px" >查询</el-button>             </div>             <div>                 <el-button type="primary" style="float: right" >+添加器材</el-button>             </div>         </el-form>          <!-- 分页查询 -->         <div>             <el-table :data="records" stripe style="width: 100%">                 <el-table-column prop="name" label="器材名称" width="180">                 </el-table-column>                 <el-table-column prop="img" label="图片" width="180">                 </el-table-column>                 <el-table-column prop="number" label="数量" width="180">                 </el-table-column>                 <el-table-column prop="comment" label="描述" width="180">                 </el-table-column>                 <el-table-column prop="status" label="器材状态">                     <template slot-scope="scope">{{ scope.row.status === 0 ? "禁用" : "启用" }}</template>                 </el-table-column>                 <el-table-column prop="updateTime" label="最后操作时间"></el-table-column>                  <el-table-column label="操作">                     <template slot-scope="scope">                         <el-button type="text" @click="handleUpdateStu(scope.row)">修改</el-button>                         <el-button type="text" @click="handleStartOrStop(scope.row)">{{ scope.row.status === 0 ? "启用" :             "禁用"                             }}</el-button>                     </template>                 </el-table-column>             </el-table>         </div>     </div>       </template>   <script>  export default {     data() {         return {             name: '',        //器材名称,对应上面的输入框             page: 1,         //页码             pageSize: 10,    // 每页记录数             total: 0,         //总记录数             records: []      //当前页要展示的数据集合         }     },     }  </script>

src\views\equipment\Equipment.vue

<template>     <div>         <el-form :inline="true" :model="formInline" class="demo-form-inline">             <div style="float: left">                 <label style="margin-right: 5px">学生姓名: </label>                 <el-input v-model="name" placeholder="请输入学生姓名" style="width: 40%" />                 <el-button type="primary" style="margin-left: 20px" @click="pageQuery()">查询</el-button>             </div>             <div>                 <el-button type="primary" style="float: right" @click="handleAddStu">+添加学生</el-button>             </div>         </el-form>         <br>         <br>         <br>         <div>             <el-table :data="records" stripe style="width: 100%">                 <el-table-column prop="name" label="学生姓名" width="180">                 </el-table-column>                 <el-table-column prop="username" label="账号" width="180">                 </el-table-column>                 <el-table-column prop="phone" label="手机号">                 </el-table-column>                 <el-table-column prop="status" label="账号状态">                     <template slot-scope="scope">{{ scope.row.status === 0 ? "禁用" : "启用" }}</template>                 </el-table-column>                 <el-table-column prop="updateTime" label="最后操作时间">                 </el-table-column>                 <el-table-column label="操作">                     <template slot-scope="scope">                         <el-button type="text" @click="handleUpdateStu(scope.row)">修改</el-button>                         <el-button type="text" @click="handleStartOrStop(scope.row)">{{ scope.row.status === 0 ? "启用" :             "禁用"                             }}</el-button>                     </template>                 </el-table-column>             </el-table>         </div>         <br>         <div>             <el-pagination class="pageList" @size-change="handleSizeChange" @current-change="handleCurrentChange"                 :current-page="page" :page-sizes="[10, 20, 30, 40]" :page-size="pageSize"                 layout="total, sizes, prev, pager, next, jumper" :total="total">             </el-pagination>         </div>     </div> </template>   <script> // import request from '@/utils/request' import { page, startOrStopStatus } from '@/api/Student'  export default {     data() {         return {             name: '',        //学生姓名,对应上面的输入框             page: 1,         //页码             pageSize: 10,    // 每页记录数             total: 0,         //总记录数             records: []      //当前页要展示的数据集合         }     },     created() {         this.pageQuery()     },     methods: {         pageQuery() {             //准备参数             const params = {                 page: this.page,                 pageSize: this.pageSize,                 name: this.name             }              /* request({                 url: "/api/admin/student/page",               // 请求地址                 method: "get",                      // 请求方法                 params: params,                                        headers: {                            // 请求头                     "Content-Type": "application/json",                 },             }) */             page(params)                 .then((res) => {                     //解析结果                     if (res.data.code === 1) {                         this.total = res.data.data.total                         this.records = res.data.data.records                     }                 }).catch(err => {                     this.$router.push("/login");                 })         },         //每页记录数发生变化时触发         handleSizeChange(pageSize) {             this.pageSize = pageSize             this.pageQuery()         },         //page发生变化时触发         handleCurrentChange(page) {             this.page = page             this.pageQuery()         },          //新增员工         handleAddStu() {             this.$router.push('/student/addStudent')         },          //启用禁用员工状态         handleStartOrStop(row) {             //判断账号是否是管理员账号,不能更改管理员账号             if (row.username === 'admin') {                 this.$message.error("这是管理员账号,不允许更改!")                 return             }              this.$confirm('是否确认修改员工状态?', '提示', {                 confirmButtonText: '确定',                 cancelButtonText: '取消',                 type: 'warning'             }).then(() => {                 const p = {                     id: row.id,                     status: !row.status ? 1 : 0                 }                                  startOrStopStatus(p)                 .then(res =>{                     if(res.data.code === 1){                         this.$message.success("状态修改成功!")                         this.pageQuery()                     }                 })              })         },         //修改编辑学生信息         handleUpdateStu(row){             if(row.username === 'admin'){                 this.$message.error("这是管理员账号,不允许修改!!")                 return             }             //跳转到修改页面,通过地址栏传递参数             this.$router.push({ path: '/student/addStudent', query: {id: row.id}})         }      } } </script> 

src\api\Equipment.js

import request from '@/utils/request'  /* 分页查询 */ export const pageEquipment = (params) =>     request({         'url': '/api/admin/equipment/page',         'method': 'get',         params: params     })

新增器材

src\router\index.js

src\views\equipment\Equipment.vue

src\views\equipment\addEquipment.vue

<template>     <div>hello</div> </template>

测试

完善表单

请求

src\api\Equipment.js

import request from '@/utils/request'  /* 分页查询 */ export const pageEquipment = (params) =>     request({         'url': '/api/admin/equipment/page',         'method': 'get',         params: params     })        /* 新增器材 */ export const addEquipment = (params) =>     request({         'url': '/api/admin/equipment',         'method': 'post',         data: params     }) 

新增板块的界面

src\views\equipment\addEquipment.vue

<template>     <div class="form-container">         <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">             <el-form-item label="器材名称:" required prop="name">                 <el-input v-model="ruleForm.name"></el-input>             </el-form-item>              <el-form-item label="数量:" required prop="number">                 <el-input v-model="ruleForm.number"></el-input>             </el-form-item>              <el-form-item label="描述" prop="comment">                 <el-input v-model="ruleForm.comment"></el-input>             </el-form-item>              <el-form-item label="器材图片:" prop="img">                 <div class="img-upload-container">                     <!-- 监听 update:imageUrl 事件并更新 ruleForm.img -->                     <img-upload @update:imageUrl="handleImageUrlUpdate" />                     <!-- <img-upload :prop-image-url="ruleForm.img"></img-upload> -->                     <span class="img-upload-instructions">图片大小不超过2M<br>仅能上传 PNG JPEG                         JPG类型图片<br>建议上传200*200或300*300尺寸的图片</span>                 </div>             </el-form-item>              <el-form-item>                 <el-button type="primary" @click="submitForm('ruleForm')">保存</el-button>                 <el-button @click="$router.push('/equipment');">返回</el-button>             </el-form-item>            </el-form>      </div>  </template>  <script> import ImgUpload from '@/components/img-upload/img-upload.vue' import { addEquipment } from '@/api/Equipment'  export default {      components: {         ImgUpload,     },      data() {          return {             // imageUrl: '',             ruleForm: {                 name: '',                 img: '',                 number: '',                 comment: ''             },             rules: {                 name: [                     { required: true, message: '请输入器材名称', trigger: 'blur' }],                 number: [                     { required: true, message: '请输入器材数量', trigger: 'blur' }],             },          }     },     methods: {         submitForm(formName) {             this.$refs[formName].validate((valid) => {                 if (valid) {                     alert(this.ruleForm.img)                     if (!this.ruleForm.img)                         return this.$message.error('套餐图片不能为空')                     addEquipment(this.ruleForm)                         .then((res) => {                             if (res.data.code === 1) {                                 this.$message.success("添加成功!")                                 this.$router.push('/equipment')                             } else {                                 this.$message.error("res.data.msg")                             }                         })                 } else {                     console.log('error submit!!');                     return false;                 }             });         },         handleImageUrlUpdate(newImageUrl) {             alert(newImageUrl)             this.ruleForm.img = newImageUrl;         }     }, }  </script>  <style scoped> .form-container {     display: flex;     justify-content: center;     align-items: center;     height: 70vh;     /* 或者你想要的任何高度 */     width: 100%;     max-width: 600px;     /* 限制最大宽度以适应较小的屏幕 */     margin: 0 auto;     /* 水平居中 */     padding: 20px;     /* 内边距 */     background-color: #ffffff;     /* 背景颜色 */     border-radius: 8px;     /* 圆角 */     box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);     /* 阴影效果 */ }    /* 为提示文字设置样式 */ .img-upload-instructions {     font-size: 12px;     /* 根据需要调整字体大小 */     color: #666;     /* 根据需要调整颜色 */     margin-bottom: 5px;     /* 可选: 添加底部边距 */ }  /* 为整个上传组件设置样式 */ .img-upload-container {     display: flex;     /* 使用Flex布局 */     align-items: center;     /* 垂直居中 */     gap: 10px;     /* 间距 */ } </style> 

上传文件OSS的逻辑

src\components\img-upload\img-upload.vue

<template>   <div class="upload-item">     <el-upload ref="uploadfiles" :accept="type" :class="{ borderNone: imageUrl }" class="avatar-uploader"       action="/api/admin/common/upload" :show-file-list="false" :on-success="handleAvatarSuccess"       :on-remove="handleRemove" :on-error="handleError" :before-upload="beforeAvatarUpload" :headers="headers">       <img v-if="imageUrl" :src="imageUrl" class="avatar">        <i v-else class="el-icon-plus avatar-uploader-icon" />       <span v-if="imageUrl" class="el-upload-list__item-actions">         <span class="el-upload-span" @click.stop="oploadImgDel">           删除图片         </span>         <span class="el-upload-span"> 重新上传 </span>       </span>     </el-upload>     <p class="upload-tips">       <slot />     </p>   </div> </template>  <script> import { getToken } from '@/utils/cookies'  export default {   name: 'UploadImage',   props: {     type: {       type: String,       default: '.jpg,.jpeg,.png'     },     size: {       type: Number,       default: 2     },     propImageUrl: {       type: String,       default: ''     }   },   data() {     return {       headers: {         token: getToken()       },       imageUrl: ''     };   },   methods: {     handleRemove() {       // 方法实现     },     oploadImgDel() {       this.imageUrl = '';       this.$emit('imageChange', this.imageUrl);     },     beforeAvatarUpload(file) {       const isLt2M = file.size / 1024 / 1024 < this.size;       if (!isLt2M) {         this.$message({           message: `上传文件大小不能超过${this.size}M!`,           type: 'error'         });         return false;       }     },     handleError(err, file, fileList) {       console.log(err, file, fileList, 'handleError');       this.$message({         message: '图片上传失败',         type: 'error'       });     },     handleAvatarSuccess(response) {       this.imageUrl = `${response.data}`;       // 发出一个事件,包含新的图片 URL         this.$emit('update:imageUrl', this.imageUrl);       }   },   watch: {     propImageUrl: function (val) {       this.imageUrl = val;     }   } }; </script>   <style lang='scss'> .borderNone {   .el-upload {     border: 1px solid #d9d9d9 !important;   } } </style> <style scoped lang="scss"> .avatar-uploader .el-icon-plus:after {   position: absolute;   display: inline-block;   content: ' ' !important;   left: calc(50% - 20px);   top: calc(50% - 40px);   width: 40px;   height: 40px;   // background: url('./../../assets/icons/icon_upload@2x.png') center center no-repeat;   background-size: 20px; }  .el-upload-list__item-actions:hover .upload-icon {   display: inline-block; }  .el-icon-zoom-in:before {   content: '\E626'; }  .el-icon-delete:before {   content: '\E612'; }  .el-upload-list__item-actions:hover {   opacity: 1; }  .upload-item {     .el-form-item__content {     width: 500px !important;   }    display: flex;   align-items: center;   border: 1px solid #ccc;   /* 添加边框*/   width: 200px;   /* 设置宽度 */   height: 200px;   /* 设置高度,使之与宽度相同 */ }  .upload-tips {   font-size: 12px;   color: #666666;   display: inline-block;   line-height: 17px;   margin-left: 36px; }  .el-upload-list__item-actions {   position: absolute;   width: 100%;   height: 100%;   left: 0;   top: 0;   cursor: default;   text-align: center;   color: #fff;   opacity: 0;   font-size: 20px;   background-color: rgba(0, 0, 0, 0.5);   transition: opacity 0.3s;   display: flex;   justify-content: center;   align-items: center;   flex-direction: column; }  .avatar-uploader .el-upload {   border: 1px dashed #d9d9d9;   border-radius: 6px;   cursor: pointer;   position: relative;   overflow: hidden; }  .avatar-uploader {   display: inline-block; }  .avatar-uploader .el-upload:hover {   border-color: #ffc200; }  .el-upload-span {   width: 100px;   height: 30px;   border: 1px solid #ffffff;   border-radius: 4px;   font-size: 14px;   text-align: center;   line-height: 30px; }  .el-upload-span:first-child {   margin-bottom: 20px; }  .avatar-uploader-icon {   font-size: 28px;   color: #8c939d;   width: 200px;   height: 160px;   line-height: 160px;   text-align: center; }  .avatar {   width: 200px;   height: 160px;   display: block; } </style> 

上传oss图片文件时需要的jwt令牌获取

src\utils\cookies.js

import Cookies from 'js-cookie';   // 获取令牌 export const getToken = () => sessionStorage.getItem('jwtToken');  

ps:如果出现模块找不到,不存在的时候,直接

npm install 模块

例如:

Module not found: Error: Can't resolve 'js-cookie' in 'D:\bishe\project\sems-front\src\utils'

解决方法:

这个错误表明你的项目无法找到js-cookie模块,这意味着你可能还没有安装它或者路径配置有问题。js-cookie是一个用于操作浏览器Cookies的小型JavaScript库。

解决方案

安装 js-cookie

确保你已经安装了js-cookie。你可以通过运行以下命令来安装它:

npm install js-cookie --save

或者如果你使用的是Yarn:

yarn add js-cookie

测试:

ps:OSS折磨死我了,踩了无数的坑,全靠各种搜索资料,卡了我2天,呜呜呜,麻了,有什么不知道的真可以问我,呜呜呜,你们踩的坑我应该都踩过,麻了

未完。。。

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!