页面搭建

  1. <template>
  2. <div class="employees-container">
  3. <div class="app-container">
  4. <el-card>
  5. <!-- 放置表单 -->
  6. <el-form ref="userForm" label-width="120px" :model="userInfo" :rules="rules" style="margin-left: 120px; margin-top:30px">
  7. <el-form-item label="姓名:" prop="username">
  8. <el-input v-model="userInfo.username" style="width:300px" />
  9. </el-form-item>
  10. <el-form-item label="手机">
  11. <el-input v-model="userInfo.mobile" disabled style="width:300px" />
  12. </el-form-item>
  13. <el-form-item label="入职时间">
  14. <el-date-picker
  15. v-model="userInfo.timeOfEntry"
  16. type="date"
  17. value-format="yyyy-MM-dd"
  18. />
  19. </el-form-item>
  20. <el-form-item label="员工头像" />
  21. <!-- 保存个人信息 -->
  22. <el-row class="inline-info" type="flex" justify="center">
  23. <el-col :span="12">
  24. <el-button type="primary">保存更新</el-button>
  25. <el-button @click="$router.back()">返回</el-button>
  26. </el-col>
  27. </el-row>
  28. </el-form>
  29. </el-card>
  30. </div>
  31. </div>
  32. </template>
  33. <script>
  34. export default {
  35. data() {
  36. return {
  37. userInfo: {},
  38. rules: {}
  39. }
  40. }
  41. }
  42. </script>
  1. {
  2. path: 'detail',
  3. component: () => import('@/views/employees/detail'),
  4. hidden: true, // 不在左侧菜单显示
  5. meta: {
  6. title: '员工详情'
  7. }
  8. }

需要根据id查询到数据 在跳转路由的时候需要传参 传id 给查看 绑定事件 触发的时候跳转路由且传参

  1. goDetail(id) {
  2. this.$router.push({
  3. path: '/employees/detail',
  4. query: {
  5. id
  6. }
  7. })
  8. }

数据回显

需要的接口已经在之前提供过了 **src/api/user.js** 调用接口的时候传入路由传递的参数(this.$route.query.id)

  1. mounted() {
  2. this.getDetail()
  3. },
  4. methods: {
  5. async getDetail() {
  6. const res = await getUserDetailById(this.$route.query.id)
  7. this.userInfo = res.data
  8. console.log(res)
  9. }
  10. }

修改功能

使用最新的数据覆盖原先的数据,作为接口提交的数据

  1. async save() {
  2. await changeUserDetailById(this.userInfo)
  3. this.$message.success('修改信息成功')
  4. console.log(this.userInfo)
  5. this.$router.go(-1)
  6. }

头像上传组件

action必填属性 这里用不到 所以填入# on-success 上传成功后 可以绑定函数 before-upload上传前 可以绑定函数 http-request 属性 覆盖默认上传,可以自定上传方式 封装好后用之前封装的插件 全局注册这个组件 并渲染到页面中

  1. <template>
  2. <div>
  3. <el-upload
  4. class="avatar-uploader"
  5. action="#"
  6. :show-file-list="false"
  7. :on-success="handleAvatarSuccess"
  8. :before-upload="beforeAvatarUpload"
  9. :http-request="upload"
  10. >
  11. <img v-if="imageUrl" :src="imageUrl" class="avatar">
  12. <i v-else class="el-icon-plus avatar-uploader-icon" />
  13. </el-upload>
  14. </div>
  15. </template>
  16. <script>
  17. export default {
  18. data() {
  19. return {
  20. imageUrl: ''
  21. }
  22. },
  23. methods: {
  24. upload(file) {
  25. console.log(file)
  26. },
  27. handleAvatarSuccess(res, file) {
  28. this.imageUrl = URL.createObjectURL(file.raw)
  29. },
  30. beforeAvatarUpload(file) {
  31. const isPNG = file.type === 'image/png'
  32. const isLt2M = file.size / 1024 / 1024 < 2
  33. if (!isPNG) {
  34. this.$message.error('上传头像图片只能是 PNG 格式!')
  35. }
  36. if (!isLt2M) {
  37. this.$message.error('上传头像图片大小不能超过 2MB!')
  38. }
  39. return isPNG && isLt2M
  40. }
  41. }
  42. }
  43. </script>
  44. <style>
  45. .avatar-uploader .el-upload {
  46. border: 1px dashed #d9d9d9;
  47. border-radius: 6px;
  48. cursor: pointer;
  49. position: relative;
  50. overflow: hidden;
  51. }
  52. .avatar-uploader .el-upload:hover {
  53. border-color: #409eff;
  54. }
  55. .avatar-uploader-icon {
  56. font-size: 28px;
  57. color: #8c939d;
  58. width: 178px;
  59. height: 178px;
  60. line-height: 178px;
  61. text-align: center;
  62. }
  63. .avatar {
  64. width: 178px;
  65. height: 178px;
  66. display: block;
  67. }
  68. </style>

实现头像的上传和回显

根据cos的上传Api实现上传功能

安装npm i cos-js-sdk-v5

  1. // 引入必要的COS模块
  2. const COS = require('cos-js-sdk-v5')
  3. // 实例化对象
  4. const cos = new COS({
  5. SecretId: 'xxxx', // 身份识别ID
  6. SecretKey: 'xxxx' // 身份秘钥
  7. })

使用cos对象完成上传

  1. upload(res) {
  2. // 执行上传操作
  3. cos.putObject({
  4. Bucket: 'xxxxxx', /* 存储桶 */
  5. Region: 'xxxx', /* 存储桶所在地域,必须字段 */
  6. Key: res.file.name, /* 文件名 */
  7. StorageClass: 'STANDARD', // 上传模式, 标准模式
  8. Body: res.file, // 上传文件对象
  9. onProgress: (progressData) => {
  10. console.log(JSON.stringify(progressData))
  11. }
  12. }, (err, data) => {
  13. console.log(err || data)
  14. // 上传成功之后
  15. if (data.statusCode === 200) {
  16. this.imageUrl = `https:${data.Location}`
  17. }
  18. })
  19. }
  1. upload({ file }) {
  2. console.log(file)
  3. // 拿到了 file对象
  4. // 上传配置 cos的实例对象提供
  5. cos.putObject({
  6. Bucket: 'puxinman-1312633199', /* 存储桶 */
  7. Region: 'ap-beijing', /* 存储桶所在地域,必须字段 */
  8. Key: file.name, /* 文件名 */
  9. StorageClass: 'STANDARD', // 上传模式, 标准模式
  10. Body: file, // 上传文件对象
  11. onProgress: (progressData) => {
  12. // 在上传过程中进行上传进度的展示的 告诉我们当前上传了多少了
  13. console.log(JSON.stringify(progressData))
  14. }
  15. }, (err, data) => {
  16. console.log(err || data)
  17. // 上传成功之后
  18. console.log('当前的返回信息:', data)
  19. if(data.statusCode === 200){
  20. this.imageUrl = `https:${data.Location}`
  21. }
  22. })
  23. },

上传进度条的实现

找到一个回调函数,知道当前上传进度是多少 需要使用一个进度条组件 把进度条渲染上去

  1. <template>
  2. <div>
  3. <el-upload
  4. class="avatar-uploader"
  5. action="#"
  6. :show-file-list="false"
  7. :on-success="handleAvatarSuccess"
  8. :before-upload="beforeAvatarUpload"
  9. :http-request="upload"
  10. >
  11. <img v-if="imageUrl" :src="imageUrl" class="avatar">
  12. <i v-else class="el-icon-plus avatar-uploader-icon" />
  13. <el-progress class="progress" v-if="percentageFlag" type="circle" :percentage="percentage" />
  14. </el-upload>
  15. </div>
  16. </template>
  17. <script>
  18. // 引入必要的COS模块
  19. const COS = require('cos-js-sdk-v5')
  20. // 实例化对象
  21. const cos = new COS({
  22. SecretId: 'AKIDLYVCdngIdhU0FCsIQHrACxHK6bpmSs1t', // 身份识别ID
  23. SecretKey: 'd1D9oENFrCG3ZomTt1sSlmWzB6k7D2bu' // 身份秘钥
  24. })
  25. export default {
  26. data() {
  27. return {
  28. imageUrl: '',
  29. percentage: 0,
  30. percentageFlag: false
  31. }
  32. },
  33. methods: {
  34. upload({ file }) {
  35. console.log(file)
  36. // 拿到了 file对象
  37. // 上传配置 cos的实例对象提供
  38. cos.putObject({
  39. Bucket: 'puxinman-1312633199', /* 存储桶 */
  40. Region: 'ap-beijing', /* 存储桶所在地域,必须字段 */
  41. Key: file.name, /* 文件名 */
  42. StorageClass: 'STANDARD', // 上传模式, 标准模式
  43. Body: file, // 上传文件对象
  44. onProgress: (progressData) => {
  45. this.percentageFlag = true
  46. // 在上传过程中进行上传进度的展示的 告诉我们当前上传了多少了
  47. console.log(JSON.stringify(progressData))
  48. this.percentage = progressData.percent
  49. }
  50. }, (err, data) => {
  51. console.log(err || data)
  52. // 上传成功之后
  53. // console.log('当前的返回信息:', data)
  54. if (data.statusCode === 200) {
  55. this.imageUrl = `https:${data.Location}`
  56. }
  57. this.percentageFlag = false
  58. })
  59. }
  60. }
  61. </script>
  62. <style>
  63. .progress {
  64. position: absolute;
  65. display: flex;
  66. top: 50%;
  67. left: 50%;
  68. transform: translate(-50%,-50%);
  69. background: #fff;
  70. }
  71. </style>

业务使用

将图片的url地址传到userInfo的staffPhoto中 子传父

  1. // 子组件
  2. // 上传成功之后
  3. // console.log('当前的返回信息:', data)
  4. if (data.statusCode === 200) {
  5. this.imageUrl = `https:${data.Location}`
  6. this.$emit('get_url', this.imageUrl)
  7. // 父组件
  8. <upload-img @get_url="getUrl" />
  9. // 子传父
  10. getUrl(url) {
  11. this.userInfo.staffPhoto = url
  12. },

图片刷新就会消失 因为接口返回的数据返回到了userInfo里面 子组件内还没有节后到 需要父传子一下 同步prop和data的数据 最佳方案是watch 数据发生变化就会执行

  1. // 父组件
  2. <upload-img :url="userInfo.staffPhoto"/>
  3. // 子组件
  4. props: {
  5. url: {
  6. type: String,
  7. default: ''
  8. }
  9. },
  10. watch: {
  11. // 同步 props 和 data 的数据变化
  12. url() {
  13. this.imageUrl = this.url
  14. }

v-model优化

语法糖 概念:基于一些旧的而语法复杂的语法经过一定的封装变成简单的语法,把复杂度内置 开发人员写起来更加简单 v-model 1.会在组件上绑定一个value的的属性proprs 2.会在组件身上绑定一个默认名为 input的自定义事件 3.当在组件内部通过this.$emit()去触发input事件的时候 事件参数会被自动赋值给v-modle绑定的属性身上

  1. // 父组件
  2. <upload-img v-model="userInfo.staffPhoto" />
  3. // 子组件
  4. props: {
  5. value: {
  6. type: String,
  7. default: ''
  8. }
  9. },
  10. watch: {
  11. // 同步 props 和 data 的数据变化
  12. value() {
  13. this.imageUrl = this.value
  14. }
  15. },
  16. if (data.statusCode === 200) {
  17. this.imageUrl = `https:${data.Location}`
  18. this.$emit('input', this.imageUrl)
  19. }

图片渲染到列表中

image组件 查看elementUI 占位和加载失败都需要插槽 <template #placeholder>占位插槽 <template #error> 错误插槽

  1. <template #default="{row}">
  2. <el-image :src="row.staffPhoto" style="width:100px; height: 100px;border-radius:50px;">
  3. <template #placeholder>
  4. 加载中...
  5. </template>
  6. <template #error>
  7. <img width="100" height="100" src="@/assets/common/bigUserHeader.png" alt="">
  8. </template>
  9. </el-image>
  10. </template>