页面搭建
<template><div class="employees-container"><div class="app-container"><el-card><!-- 放置表单 --><el-form ref="userForm" label-width="120px" :model="userInfo" :rules="rules" style="margin-left: 120px; margin-top:30px"><el-form-item label="姓名:" prop="username"><el-input v-model="userInfo.username" style="width:300px" /></el-form-item><el-form-item label="手机"><el-input v-model="userInfo.mobile" disabled style="width:300px" /></el-form-item><el-form-item label="入职时间"><el-date-pickerv-model="userInfo.timeOfEntry"type="date"value-format="yyyy-MM-dd"/></el-form-item><el-form-item label="员工头像" /><!-- 保存个人信息 --><el-row class="inline-info" type="flex" justify="center"><el-col :span="12"><el-button type="primary">保存更新</el-button><el-button @click="$router.back()">返回</el-button></el-col></el-row></el-form></el-card></div></div></template><script>export default {data() {return {userInfo: {},rules: {}}}}</script>
{path: 'detail',component: () => import('@/views/employees/detail'),hidden: true, // 不在左侧菜单显示meta: {title: '员工详情'}}
需要根据id查询到数据 在跳转路由的时候需要传参 传id 给查看 绑定事件 触发的时候跳转路由且传参
goDetail(id) {this.$router.push({path: '/employees/detail',query: {id}})}
数据回显
需要的接口已经在之前提供过了
**src/api/user.js**调用接口的时候传入路由传递的参数(this.$route.query.id)
mounted() {this.getDetail()},methods: {async getDetail() {const res = await getUserDetailById(this.$route.query.id)this.userInfo = res.dataconsole.log(res)}}
修改功能
使用最新的数据覆盖原先的数据,作为接口提交的数据
async save() {await changeUserDetailById(this.userInfo)this.$message.success('修改信息成功')console.log(this.userInfo)this.$router.go(-1)}
头像上传组件
action必填属性 这里用不到 所以填入#on-success上传成功后 可以绑定函数before-upload上传前 可以绑定函数http-request属性 覆盖默认上传,可以自定上传方式 封装好后用之前封装的插件 全局注册这个组件 并渲染到页面中
<template><div><el-uploadclass="avatar-uploader"action="#":show-file-list="false":on-success="handleAvatarSuccess":before-upload="beforeAvatarUpload":http-request="upload"><img v-if="imageUrl" :src="imageUrl" class="avatar"><i v-else class="el-icon-plus avatar-uploader-icon" /></el-upload></div></template><script>export default {data() {return {imageUrl: ''}},methods: {upload(file) {console.log(file)},handleAvatarSuccess(res, file) {this.imageUrl = URL.createObjectURL(file.raw)},beforeAvatarUpload(file) {const isPNG = file.type === 'image/png'const isLt2M = file.size / 1024 / 1024 < 2if (!isPNG) {this.$message.error('上传头像图片只能是 PNG 格式!')}if (!isLt2M) {this.$message.error('上传头像图片大小不能超过 2MB!')}return isPNG && isLt2M}}}</script><style>.avatar-uploader .el-upload {border: 1px dashed #d9d9d9;border-radius: 6px;cursor: pointer;position: relative;overflow: hidden;}.avatar-uploader .el-upload:hover {border-color: #409eff;}.avatar-uploader-icon {font-size: 28px;color: #8c939d;width: 178px;height: 178px;line-height: 178px;text-align: center;}.avatar {width: 178px;height: 178px;display: block;}</style>
实现头像的上传和回显
根据cos的上传Api实现上传功能
安装npm i cos-js-sdk-v5
// 引入必要的COS模块const COS = require('cos-js-sdk-v5')// 实例化对象const cos = new COS({SecretId: 'xxxx', // 身份识别IDSecretKey: 'xxxx' // 身份秘钥})
使用cos对象完成上传
upload(res) {// 执行上传操作cos.putObject({Bucket: 'xxxxxx', /* 存储桶 */Region: 'xxxx', /* 存储桶所在地域,必须字段 */Key: res.file.name, /* 文件名 */StorageClass: 'STANDARD', // 上传模式, 标准模式Body: res.file, // 上传文件对象onProgress: (progressData) => {console.log(JSON.stringify(progressData))}}, (err, data) => {console.log(err || data)// 上传成功之后if (data.statusCode === 200) {this.imageUrl = `https:${data.Location}`}})}
upload({ file }) {console.log(file)// 拿到了 file对象// 上传配置 cos的实例对象提供cos.putObject({Bucket: 'puxinman-1312633199', /* 存储桶 */Region: 'ap-beijing', /* 存储桶所在地域,必须字段 */Key: file.name, /* 文件名 */StorageClass: 'STANDARD', // 上传模式, 标准模式Body: file, // 上传文件对象onProgress: (progressData) => {// 在上传过程中进行上传进度的展示的 告诉我们当前上传了多少了console.log(JSON.stringify(progressData))}}, (err, data) => {console.log(err || data)// 上传成功之后console.log('当前的返回信息:', data)if(data.statusCode === 200){this.imageUrl = `https:${data.Location}`}})},
上传进度条的实现
找到一个回调函数,知道当前上传进度是多少 需要使用一个进度条组件 把进度条渲染上去
<template><div><el-uploadclass="avatar-uploader"action="#":show-file-list="false":on-success="handleAvatarSuccess":before-upload="beforeAvatarUpload":http-request="upload"><img v-if="imageUrl" :src="imageUrl" class="avatar"><i v-else class="el-icon-plus avatar-uploader-icon" /><el-progress class="progress" v-if="percentageFlag" type="circle" :percentage="percentage" /></el-upload></div></template><script>// 引入必要的COS模块const COS = require('cos-js-sdk-v5')// 实例化对象const cos = new COS({SecretId: 'AKIDLYVCdngIdhU0FCsIQHrACxHK6bpmSs1t', // 身份识别IDSecretKey: 'd1D9oENFrCG3ZomTt1sSlmWzB6k7D2bu' // 身份秘钥})export default {data() {return {imageUrl: '',percentage: 0,percentageFlag: false}},methods: {upload({ file }) {console.log(file)// 拿到了 file对象// 上传配置 cos的实例对象提供cos.putObject({Bucket: 'puxinman-1312633199', /* 存储桶 */Region: 'ap-beijing', /* 存储桶所在地域,必须字段 */Key: file.name, /* 文件名 */StorageClass: 'STANDARD', // 上传模式, 标准模式Body: file, // 上传文件对象onProgress: (progressData) => {this.percentageFlag = true// 在上传过程中进行上传进度的展示的 告诉我们当前上传了多少了console.log(JSON.stringify(progressData))this.percentage = progressData.percent}}, (err, data) => {console.log(err || data)// 上传成功之后// console.log('当前的返回信息:', data)if (data.statusCode === 200) {this.imageUrl = `https:${data.Location}`}this.percentageFlag = false})}}</script><style>.progress {position: absolute;display: flex;top: 50%;left: 50%;transform: translate(-50%,-50%);background: #fff;}</style>
业务使用
将图片的url地址传到userInfo的staffPhoto中 子传父
// 子组件// 上传成功之后// console.log('当前的返回信息:', data)if (data.statusCode === 200) {this.imageUrl = `https:${data.Location}`this.$emit('get_url', this.imageUrl)// 父组件<upload-img @get_url="getUrl" />// 子传父getUrl(url) {this.userInfo.staffPhoto = url},
图片刷新就会消失 因为接口返回的数据返回到了userInfo里面 子组件内还没有节后到 需要父传子一下 同步prop和data的数据 最佳方案是watch 数据发生变化就会执行
// 父组件<upload-img :url="userInfo.staffPhoto"/>// 子组件props: {url: {type: String,default: ''}},watch: {// 同步 props 和 data 的数据变化url() {this.imageUrl = this.url}
v-model优化
语法糖 概念:基于一些旧的而语法复杂的语法经过一定的封装变成简单的语法,把复杂度内置 开发人员写起来更加简单 v-model 1.会在组件上绑定一个value的的属性proprs 2.会在组件身上绑定一个默认名为 input的自定义事件 3.当在组件内部通过this.$emit()去触发input事件的时候 事件参数会被自动赋值给v-modle绑定的属性身上
// 父组件<upload-img v-model="userInfo.staffPhoto" />// 子组件props: {value: {type: String,default: ''}},watch: {// 同步 props 和 data 的数据变化value() {this.imageUrl = this.value}},if (data.statusCode === 200) {this.imageUrl = `https:${data.Location}`this.$emit('input', this.imageUrl)}
图片渲染到列表中
image组件 查看elementUI 占位和加载失败都需要插槽
<template #placeholder>占位插槽<template #error>错误插槽
<template #default="{row}"><el-image :src="row.staffPhoto" style="width:100px; height: 100px;border-radius:50px;"><template #placeholder>加载中...</template><template #error><img width="100" height="100" src="@/assets/common/bigUserHeader.png" alt=""></template></el-image></template>
