JWT
相關無css
//更新文件:client/src/views/personal-panel/index.vue ... <script> import http from '@/utils/http' export default { data () { return { loginer: {} } }, async created () { const { id } = this.$store.state.loginer const res = await http.get(`/users/${id}`) this.loginer = res.data } } </script>
在登陸的時候,已經將登陸用戶信息存儲到vuex
中,經過用戶ID查詢用戶詳細信息。html
// 更新文件: server/router/users.js ... const { list, get, register, login, update } = require('../control/users'); ... { path: '/:id', method: 'GET', handle: get }, ...
// 更新文件:server/control/users.js async function get (ctx) { const { id } = ctx.params; try { const user = await userModel.findOne({ _id: id }).select('+telephone +email'); //新增查詢除默認外的字段 if (user) { ctx.body = { code: '200', data: user, msg: '成功' } return; } throw('請覈對參數') } catch (err) { ctx.body = { code: '403', data: null, msg: err.message } } } ... module.exports = { ... get, ... }
userModel.findOne({_id: id})
默認查出的是Schema
沒有設置select: false
的字段,若是須要其它字段的話,須要userModel.findOne({_id: id}).select('+telephone +email');
新增字段ctx.params
獲取匹配路由:id
參數。// 更新文件:client/src/views/personal-panel/index.vue <template> <div class="panel-container"> <div class="panel-avatar"> <el-upload class="avatar-uploader" v-bind="uploadForm"> <img v-if="imageUrl" :src="imageUrl" class="avatar"> <i v-else class="el-icon-user"></i> </el-upload> </div> <div class="panel-main"> <h3 class="panel-title">{{loginer.alias || loginer.account}}</h3> <ul class="panel-content"> <li class="panel-item"> <label class="panel-item-lanel">賬號:</label> <span class="panel-item-value">{{loginer.account}}</span> </li> <li class="panel-item"> <label class="panel-item-lanel">郵箱:</label> <span class="panel-item-value">{{loginer.email}}</span> </li> <li class="panel-item"> <label class="panel-item-lanel">電話:</label> <span class="panel-item-value">{{loginer.telephone}}</span> </li> </ul> <div class="panel-controls"> <el-button class="btn-edit" type="default" @click="openFormDialog">編輯</el-button> </div> </div> </div> </template> <script> import http from '@/utils/http' export default { methods: { openFormDialog () { } }, data () { return { uploadForm: { action: '' }, imageUrl: '', loginer: {} } }, async created () { const { id } = this.$store.state.loginer const res = await http.get(`/users/${id}`) this.loginer = res.data } } </script> <style lang="scss" scoped> @import '~@/stylesheets/layout.scss'; @import './index.scss'; </style>
// 新建文件:client/src/views/personal-panel/index.scss .panel-container { @include flex($item: flex-start); .panel-avatar { width: 160px; } .panel-main { flex: 1; color: #525975; line-height: 2; padding: 0 40px; font-size: 14px; .panel-title { color: #2e3242; font-size: 24px; } } .panel-controls { margin-top: 20px; } } .avatar-uploader{ /deep/ { .el-upload { border: 1px dashed #d9d9d9; border-radius: 100px; cursor: pointer; position: relative; overflow: hidden; } .el-upload:hover { border-color: #409EFF; } .el-icon-user { font-size: 70px; color: #8c939d; width: 160px; height: 160px; line-height: 160px; text-align: center; } .avatar { width: 160px; height: 160px; display: block; } } }
展現效果
前端
// 更新文件:client/src/views/personal-panel/index.vue <template> <div class="panel-container"> <div class="panel-avatar"> <el-upload class="avatar-uploader" v-bind="uploadForm"> <img v-if="imageUrl" :src="imageUrl" class="avatar"> <i v-else class="el-icon-user"></i> </el-upload> </div> <div class="panel-main"> <h3 class="panel-title">{{loginer.alias || loginer.account}}</h3> <ul class="panel-content"> <li class="panel-item"> <label class="panel-item-lanel">賬號:</label> <span class="panel-item-value">{{loginer.account}}</span> </li> <li class="panel-item"> <label class="panel-item-lanel">郵箱:</label> <span class="panel-item-value">{{loginer.email}}</span> </li> <li class="panel-item"> <label class="panel-item-lanel">電話:</label> <span class="panel-item-value">{{loginer.telephone}}</span> </li> </ul> <div class="panel-controls"> <el-button class="btn-edit" type="default" @click="openFormDialog">編輯</el-button> </div> </div> <el-dialog :title="dialogForm.title" :visible.sync="dialogForm.visible"> <el-form :ref="dialogForm.formRef" :model="dialogForm.form" :rules="dialogForm.rules"> <el-form-item label="賬號" prop="account"> <el-input v-model="dialogForm.form.account"></el-input> </el-form-item> <el-form-item label="暱稱" prop="alias"> <el-input v-model="dialogForm.form.alias"></el-input> </el-form-item> <el-form-item label="郵箱" prop="email"> <el-input type="email" v-model="dialogForm.form.email"></el-input> </el-form-item> <el-form-item label="電話" prop="telephone"> <el-input type="telephone" v-model="dialogForm.form.telephone"></el-input> </el-form-item> </el-form> <div slot="footer" class="dialog-footer"> <el-button @click="dialogForm.visible = false">取 消</el-button> <el-button type="primary" @click="submitForm">確 定</el-button> </div> </el-dialog> </div> </template> <script> import http from '@/utils/http' export default { methods: { openFormDialog () { this.dialogForm.visible = true }, async submitForm () { try { const valid = await this.$refs[this.dialogForm.formRef].validate() if (valid) { const res = await http.patch( `/users/${this.userId}`, { ...this.dialogForm.form } ) if (res.code === '200') { const { account, alias } = res.data this.$store.commit( 'putLoginer', { account, alias } ) // 更新vuex狀態 this.loginer = Object.assign( {}, this.loginer, { ...res.data } ) // 更新展現的默認值 this.$set(this.dialogForm, 'form', Object.assign( {}, this.dialogForm.form, { ...res.data } )) // 更新彈窗默認值 this.dialogForm.visible = false } else { this.$message({ type: 'error', message: res.msg }) } } } catch (err) { console.error(err) } } }, data () { return { uploadForm: { action: '' }, imageUrl: '', loginer: {}, dialogForm: { visible: false, title: '編輯', formRef: 'dialogForm', form: { account: '', alias: '', email: '', telephone: '' }, rules: { account: [ { required: true, message: '請輸入賬號', trigger: 'blur' }, { min: 5, message: '長度至少5個字符', trigger: 'blur' } ], alias: [ { required: true, message: '請輸入暱稱', trigger: 'blur' }, { min: 1, max: 15, message: '長度不能超過十五個字符', trigger: 'blur'} ], email: [ { type: 'email', required: true, message: '請輸入郵箱', trigger: 'blur' } ], telephone: [ { required: true, message: '請輸入手機號碼', trigger: 'blur' }, { validator: (rule, value, cb) => { if (/^1[0-9]{10}$/.test(value)) { cb() } else { cb(new Error('手機號碼格式錯誤')) } }, trigger: 'blur' } ] } } } }, computed: { userId () { return this.$store.state.loginer.id } }, async created () { // 調用完初始化接口時,須要賦展現初始值 const res = await http.get(`/users/${this.userId}`) if (res.code === '200') { this.loginer = res.data this.dialogForm.form = {...res.data} this.imageUrl = res.data.avatar } else { this.$message({ type: 'error', message: '獲取用戶信息失敗' }) } } } </script>
get
方法調用/users/:id
接口後,須要給用戶設初始值。patch
方法調用/users/:id
接口,更新用戶信息後,要更新vuex
存儲的狀態,更新展現的用戶信息,更新彈窗初始值。展現效果:
vue
// 更新文件:server/control/users.js ... async function update (ctx) { const { id } = ctx.params; const payload = ctx.request.body; try { await userModel.updateOne( { _id: id }, { ...payload } ); ctx.body = { code: '200', data: { id, ...payload }, msg: '更新成功' } } catch (err) { ctx.body = { code: '403', data: null, msg: '請覈查參數' } } } ...
測試結果:
vuex
Model操做api