十、编辑用户资料
创建组件并配置路由
1、创建 views/user/index.vue
<template>   <div>     <van-nav-bar title="个人信息" left-arrow right-text="保存" />     <van-cell-group>       <van-cell title="头像" is-link>         <van-image           round           width="30"           height="30"           fit="cover"           src="http://toutiao.meiduo.site/FgSTA3msGyxp5-Oufnm5c0kjVgW7"         />       </van-cell>       <van-cell title="昵称" value="abc" is-link />       <van-cell title="性别" value="男" is-link />       <van-cell title="生日" value="2019-9-27" is-link />     </van-cell-group>   </div> </template>
  <script>   export default {     name: "UserIndex"   }; </script>
   | 
 
2、将该页面配置到根路由
{   name: 'user-profile',   path: '/user/profile',   component: () => import('@/views/user-profile') }
  | 
 
页面布局
<template>   <div class="user-profile">          <van-nav-bar       class="page-nav-bar"       title="个人信息"       left-arrow       @click-left="$router.back()"     />     
           <van-cell class="avatar-cell" title="头像" is-link center>       <van-image         class="avatar"         round         fit="cover"         src="https://img.yzcdn.cn/vant/cat.jpeg"       />     </van-cell>     <van-cell title="昵称" value="内容" is-link />     <van-cell title="性别" value="内容" is-link />     <van-cell title="生日" value="内容" is-link />        </div> </template>
  <script> export default {   name: 'UserProfile',   components: {},   props: {},   data () {     return {}   },   computed: {},   watch: {},   created () {},   mounted () {},   methods: {} } </script>
  <style scoped lang="less"> .user-profile {   .avatar-cell {     .van-cell__value {       display: flex;       flex-direction: row-reverse;     }     .avatar {       width: 60px;       height: 60px;     }   } } </style>
 
   | 
 
展示用户信息
思路:
- 找到数据接口
 
- 封装请求方法
 
- 请求获取数据
 
- 模板绑定
 
1、在 api/user.js 中添加封装数据接口
2、在 views/user/index.vue 组件中请求获取数据
3、模板绑定
修改昵称
一、准备弹出层
二、封装组件
三、页面布局
四、基本功能处理
五、更新完成
修改性别
修改生日
修改头像
图片上传预览
方式一:结合服务器的图片上传预览

方式二:纯客户端实现上传图片预览
 const file = fileInput.files[0]
 
  img.src = window.URL.createObjectURL(file)
 
  | 
 
客户端上传预览示例:
<!DOCTYPE html> <html lang="en"> <head>   <meta charset="UTF-8">   <title>客户端图片上传预览示例</title>   <style>     .img-wrap {       width: 200px;       height: 200px;       border: 1px solid #ccc;     }
      img {       max-width: 100%;     }   </style> </head> <body>   <h1>客户端图片上传预览示例</h1>   <div class="img-wrap">     <img src="" alt="" id="img">   </div>   <br>   <input type="file" id="file" onchange="onFileChange()">   <script>     const img = document.querySelector('#img')     const file = document.querySelector('#file')
      function onFileChange() {              const fileObj = file.files[0]       const data = window.URL.createObjectURL(fileObj)       img.src = data     }   </script> </body> </html>
 
   | 
 
接下来就是在项目中使用纯客户端的方式处理用户头像上传预览。
在 views/user/index.vue 组件中:
<template>   <div>     <van-nav-bar title="个人信息" left-arrow right-text="保存" />     <van-cell-group>       +       <van-cell title="头像" is-link @click="onChangePhoto">         <van-image round width="30" height="30" :src="user.photo" />       </van-cell>       <van-cell title="昵称" :value="user.name" is-link />       <van-cell title="性别" :value="user.gender === 0 ? '男' : '女'" is-link />       <van-cell title="生日" :value="user.birthday" is-link />     </van-cell-group>
      
 
      + <input type="file" hidden ref="file" @change="onFileChange" />   </div> </template>
  <script>   import { getProfile } from '@/api/user'
    export default {     name: 'UserIndex',     data () {       return {         user: {}       }     },
      created () {       this.loadUserProfile()     },
      methods: {       async loadUserProfile () {         const { data } = await getProfile()         this.user = data.data       },
    +    onChangePhoto () {         this.$refs.file.click()       },
    +    onFileChange () {         this.user.photo = window.URL.createObjectURL(this.$refs.file.files[0])       }     }   } </script>
   | 
 
头像裁切
方案一:结合服务端的图片裁切上传流程
方案二:纯客户端的图片裁切上传流程
viewMode: 1, dragMode: 'move', aspectRatio: 1, autoCropArea: 1, cropBoxMovable: false, cropBoxResizable: false, background: false, movable: true
   | 
 
保存更新
如果是基于服务端的裁切,则使用:getData 方法,该方法得到裁切的区域参数。
如果是纯客户端的图片裁切,则使用:getCroppedCanvas 方法,该方法得到裁切之后的图片对象(类似于URL.createObjectURL 方法得到的文件对象)。
步骤:
1、在 api/user.js 中添加封装数据接口
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  import request from '@/utils/request'
 
 
 
  export function login (user) {   return request({          method: 'POST',          url: '/app/v1_0/authorizations',          data: user   }) }
 
 
 
  export function followUser (userId) {   return request({     method: 'POST',     url: '/app/v1_0/user/followings',     data: {       target: userId      }   }) }
 
 
 
  export function unFollowUser (userId) {   return request({     method: 'DELETE',     url: '/app/v1_0/user/followings/' + userId   }) }
 
 
 
  export function getSelf (userId) {   return request({     method: 'GET',     url: '/app/v1_0/user'   }) }
 
 
 
  export function getProfile (userId) {   return request({     method: 'GET',     url: '/app/v1_0/user/profile'   }) }
 
 
 
  + export function updateUserPhoto (data) {   return request({     method: 'PATCH',     url: '/app/v1_0/user/photo',     data   }) }
 
 
  | 
 
2、在 views/user/index.vue 组件中保存提交
<template>   <div>     <van-nav-bar       title="个人信息"       left-arrow       right-text="保存"       +       @click-right="onSave"     />     <van-cell-group>       <van-cell title="头像" is-link @click="onChangePhoto">         <van-image round width="30" height="30" :src="user.photo" />       </van-cell>       <van-cell title="昵称" :value="user.name" is-link />       <van-cell title="性别" :value="user.gender === 0 ? '男' : '女'" is-link />       <van-cell title="生日" :value="user.birthday" is-link />     </van-cell-group>
      
 
      <input type="file" hidden ref="file" @change="onFileChange" />   </div> </template>
  <script>   + import { getProfile, updateUserPhoto } from '@/api/user'
    export default {     name: 'UserIndex',     data () {       return {         user: {}       }     },
      created () {       this.loadUserProfile()     },
      methods: {       async loadUserProfile () {         const { data } = await getProfile()         this.user = data.data       },
        onChangePhoto () {         this.$refs.file.click()       },
        onFileChange () {         const fileObj = this.$refs.file.files[0]         if (fileObj) {           this.user.photo = window.URL.createObjectURL(fileObj)         }       },
    +    async onSave () {                                                      this.$toast.loading({           duration: 0,            forbidClick: true,            loadingType: 'spinner',           message: '保存中'         })
          try {           const formData = new FormData()                      formData.append('photo', this.$refs.file.files[0])           await updateUserPhoto(formData)           this.$toast.success('保存成功')         } catch (err) {           console.log(err)           this.$toast.fail('保存失败')         }       }     }   } </script>
   |