Day09:09 - User服务(4) - 前端 - JWT token、修改个人资料

Hola,我是Charlie!
在Day08当中,我们完成了後端的JWT机制还有修改个人资料,在今天我们将完成前端的JWT机制还有修改个人资料。

================================◉‿◉=================================

首先是注册的部分,注册的话加上储存token跟username:

window.localStorage.setItem('username',this.username)
window.localStorage.setItem('token',response.data.data.token)

加上之後,注册成功即可在localStorage上储存:
https://ithelp.ithome.com.tw/upload/images/20210923/201416664h4uTyOmEr.png

接着我们可以在header component的地方加上判断是否为登入状态的程序码,并加上v-show,如果登入过後就显示特定区块:

<template slot="button-content">
	<img src="@/assets/cart.svg" alt="购物车">
</template>
<div id="shoppingCart">
	<ul>
		<li>
			大鱼
		</li>
		<li>
			小鱼
		</li>
	</ul>
</div>
</b-nav-item-dropdown>
<b-nav-item-dropdown text="会员" right>
<b-dropdown-item href="/#/login" v-show="!isLogin">登入</b-dropdown-item>
<b-dropdown-item href="/#/register" v-show="!isLogin">注册</b-dropdown-item>
<b-dropdown-item href="/#/self" v-show="isLogin">个人资料</b-dropdown-item>
<b-dropdown-item href="/#/order" v-show="isLogin">订单</b-dropdown-item>
<b-dropdown-item v-show="isLogin">登出</b-dropdown-item>
</b-nav-item-dropdown>


<script>
  export default{
    name:'kheader',
    data(){
      return {
        isLogin:false,
        username:""
      }
    },
    mounted(){
      var username = window.localStorage.getItem('username')
      var token = window.localStorage.getItem('token')
      if(username != null && token != null){
        this.username = username
        this.isLogin = true
      }
    }
  }
</script>

新增完後到首页查看,可以看到已经有变化了:
https://ithelp.ithome.com.tw/upload/images/20210923/20141666BHVGRtyByn.png

接着修改logout方法:

methods: {
  logout(){
    window.localStorage.removeItem('username')
    window.localStorage.removeItem('token')
    window.location.reload()
  }
}

接着修改登入页面,一样加上setItem:

login(data).then((response) => {
  if(response.data.code == STATUS_OK){
    window.localStorage.setItem('username',this.username)
    window.localStorage.setItem('token',response.data.data.token)
    this.$alert("登入成功").then(() => {
      window.location.href = '/#/index'
      window.location.reload()
    })
  }else{
    this.$fire({type:'error',text:response.data.data})
  }
})

https://ithelp.ithome.com.tw/upload/images/20210923/20141666kM1kto6VXk.png

接着在alert後面加上.then,设定重刷页面,以注册为例:

this.$alert("注册成功").then(() => {
  window.location.href = "/#/index"
  window.location.reload()
})

接着是修改个人资料的部分,首先在django的users中建立GET方法判断,要返回的是个人资料。

首先先加上路径:

url(r'/(?P<username>[\w]{1,55})$',views.users)

接着加上request method,还有username参数:

@logincheck('PUT','DELETE','GET')
def users(request,username = None):

接着我们在User model中加上toJson方法:

def toJson(self):
	data = {}
	data["username"] = self.name
	data["password"] = ""
	data["phone"] = self.phone
	data["address"] = self.address
	data["created_time"] = self.created_time
	data["modified_time"] = self.modified_time
	return data

接着在users view中加入查询的程序码:

elif request.method == "GET":
	if username is None:
		return R.badRequest("UserName Not Found")
	user = User.objects.filter(name = username)
	if not user:
		return R.badRequest("user does not exist")
	user = user[0]
	data = user.toJson()
	return R.ok({"data":data})

并且使用POSTMAN测试:
https://ithelp.ithome.com.tw/upload/images/20210923/20141666XkM469rcSr.png

再来是前端的部分,首先在users.js中加入function:

export function getdata(username,token){
  return axios.get(`http://${host()}:${port()}/user/${username}`,{
    headers: {
      "AUTHORIZATION":token
    }
  })
}

接着在self.vue当中新增created程序码:

created(){
  var username = window.localStorage.getItem('username')
  var token = window.localStorage.getItem('token')
  if(username != null && token != null){
    getdata(username,token).then((response) => {
      if(response.data.code == STATUS_OK){
        var rdata = response.data.data.data
        this.username = rdata.username
        this.phone = rdata.phone
        this.address = rdata.address
      }else{
        this.$fire({type:'error',text:response.data.data}).then(() => {
          window.location.href = "/#/login"
          window.location.reload()
        })
      }
    })
  }else{
    this.$fire({type:'error',text:"Please login"}).then(() => {
      window.location.href = "/#/login"
      window.location.reload()
    })
  }
}

接着是修改方法,先在users.js当中新增api接口:

export function fixdata(data,token){
  return axios.put(`http://${host()}:${port()}/user`,data,{
    headers:{
      "AUTHORIZATION":token
    }
  })
}

接着修改onSubmit方法:

onSubmit(){
	var data = {
	  "username":this.username,
	  "address":this.address,
	  "phone":this.phone
	}
	var token = window.localStorage.getItem('token')
	fixdata(data,token).then((response) => {
	  if(response.data.code == STATUS_OK){
	    this.$fire({type:'success',text:'更新成功'})
	  }else{
	    this.$fire({type:'error',text:response.data.data})
	  }
	})
}

** 如果这边onSubmit方法失效的话,可改成@click **

就可以成功更新资料了。

再来是大头贴的部分,首先新增Django models栏位:

avatar = models.ImageField(upload_to = "avatar/")

并且使用python manage.py makemigrations / migrate迁移:
https://ithelp.ithome.com.tw/upload/images/20210923/20141666bTDYsZDdt2.png

并在toJson内新增avatar栏位,这里要使用的是url的部分:

data["avatar"] = self.avatar.url

接下来在users.js中新增uploadImage方法:

export function uploadImage(data,token){
  return axios.post(`http://${host()}:${port()}/user/avatar`,data,{
    headers:{
      "AUTHORIZATION":token,
      processData: false,
      contentType: false
    }
  })
}

** 这里必须将processData跟contentType加入django的CORS白名单 **

後端的部分,档案必须使用request.FILES,文字部分必须使用request.POST:

elif request.method == "POST" and 'avatar' in request.path:
	file = request.FILES.get('avatar')
	username = request.POST.get('username')
	user = User.objects.filter(name = username)
	if not user:
		return R.badRequest("User does not exist")
	user = user[0]
	user.avatar = file
	user.save()
	return R.ok("upload success")

前端的部分先在修改大头贴前面加上b-form-file,并且加上修改方法:

<b-form-file v-model="avatar"></b-form-file>
<b-button variant="info" @click="uploadAvatar">修改大头贴</b-button>

并且在methods当中新增uploadAvatar,设定upload後刷新:

uploadAvatar(){
	var token = window.localStorage.getItem('token')
	var username = window.localStorage.getItem('username')
	let formData = new FormData()
	formData.append('avatar',this.avatar)
	formData.append('username',username)
	uploadImage(formData,token).then((response) => {
	  if(response.data.code == STATUS_OK){
	    this.$fire({type:'success',text:'上传成功'}).then(() => {
	      window.location.reload()
	    })
	  }else{
	    this.$fire({type:'error',text:response.data.data})
	  }
	})
},

接着在vue app里面新增avatarURL model,并且在img src上绑定:

<img :src="'http://localhost:8000/media/avatar/' + avatarURL" alt="" style="max-width: 100%;max-height: 100%;">

就可以修改个人资料了。
https://ithelp.ithome.com.tw/upload/images/20210923/201416668XN8vJTde6.png

================================◉‿◉=================================

Day09结束了!在今天我们完成了修改个人资料,明天我们将开始商品区块,See ya next day!


<<:  Day 08: 【结语】程序码的气味和启发

>>:  [Day 23] Node Event loop 2

Day 27 | Unity游戏开发 - 对话介面管理器

今天的文章,要说明如何使用对话管理器来制作游戏的角色对话介面。 目录 创建中文字型 对话介面配置 对...

[神经机器翻译理论与实作] 从头建立英中文翻译器 (IV)

前言 今天会将昨天训练好的翻译模型在测试资料集进行预测,若进度符合期待,将会使用 BLEU 分数来评...

[NestJS 带你飞!] DAY18 - Lifecycle Hooks

什麽是 Lifecycle Hook? 在开始介绍之前,先来了解一下何谓 生命周期 (Lifecyc...

Day2 - Yolo? 那是什麽? 能吃吗?

今天要介绍的是Object detection(物件侦测)以及CNN (Convolutional ...

网路资源

last update:2021/10/05 Yolov4 AlexeyAB (https://gi...