页面搭建
<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-picker
v-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.data
console.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-upload
class="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 < 2
if (!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', // 身份识别ID
SecretKey: '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-upload
class="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', // 身份识别ID
SecretKey: '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>