Hola,我是Charlie!
在Day08當中,我們完成了後端的JWT機制還有修改個人資料,在今天我們將完成前端的JWT機制還有修改個人資料。
================================◉‿◉=================================
首先是註冊的部分,註冊的話加上儲存token跟username:
window.localStorage.setItem('username',this.username)
window.localStorage.setItem('token',response.data.data.token)
加上之後,註冊成功即可在localStorage上儲存:
接著我們可以在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>
新增完後到首頁查看,可以看到已經有變化了:
接著修改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})
}
})
接著在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測試:
再來是前端的部分,首先在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遷移:
並在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%;">
就可以修改個人資料了。
================================◉‿◉=================================
Day09結束了!在今天我們完成了修改個人資料,明天我們將開始商品區塊,See ya next day!