目录
登录和注册
1.我的信息
编写pages\User.vue文件
<template>
<div class="member">
<div class="header-con">
<router-link :to="{ name: 'login' }" class="mui-navigate-right">
<div class="user-info">
<!-- 用户信息 -->
</div>
</router-link>
</div>
</div>
</template>
在“<!-- 用户信息 -->”后面编写如下代码,图片资源需要手动导入assets/images目录
<div class="avatar-con">
<div class="avatar">
<img src="../assets/images/avatar_default.png" class="image-info">
</div>
</div>
<div class="person-con">
<span>登录 / 注册</span>
</div>
样式:
<style lang="scss" scoped>
.member {
margin-bottom: 15px;
.header-con {
padding: 10px;
background-color: #fff;
.user-info {
position: relative;
overflow: hidden;
width: 100%;
height: 120px;
background: linear-gradient(90deg, #28a2ff, #ffd787);
box-shadow: 0 0.1rem 0.25rem #f8e3c6;
.avatar-con {
position: absolute;
left: 15px;
top: 50%;
transform: translateY(-50%);
.avatar {
width: 60px;
height: 60px;
overflow: hidden;
box-shadow: 0 2px 10px rgba(0, 0, 0, 15);
border: 1px solid hsla(0, 0%, 100%, 0.4);
border-radius: 50% 50%;
.image-info {
width: 100%;
height: 100%;
}
}
}
.person-con {
position: absolute;
left: 90px;
top: 50%;
transform: translateY(-50%);
color: #fff;
}
}
}
}
</style>
2.登录页面
src\router.js
import Login from './pages/user/Login.vue'
routes数组中添加
{ path: '/user/login', component: Login, name: 'login', meta: { title: '登录' } },
创建src\pages\user\Login.vue
<template>
<div class="login">
<div class="mui-content">
<form class="mui-input-group">
<div class="mui-input-row">
<label>账号</label>
<input v-model="loginForm.username" type="text" class="mui-input-clear mui-input" placeholder="请输入账号" />
</div>
<div class="mui-input-row">
<label>密码</label>
<input v-model="loginForm.password" type="password" class="mui-input-clear mui-input" placeholder="请输入密码" />
</div>
</form>
<div class="mui-content-padded">
<button @click="login" type="button" class="mui-btn mui-btn-block mui-btn-primary">登录</button>
<div class="link-area">
<a @click="register">还没有账号?前往注册</a>
</div>
</div>
</div>
</div>
</template>
逻辑:
<script>
export default {
data () {
return {
loginForm: {
username: '',
password: ''
}
}
},
methods: {
login () {
//登录
},
register () {
this.$router.push({ name: 'register' })
}
}
}
</script>
样式:
<style lang="scss" scoped>
.mui-input-group {
margin-top: 10px;
background-color: transparent;
}
.mui-input-group label {
width: 22%;
}
.mui-input-row:last-child {
background: #fff;
}
.mui-input-row {
margin-top: 20px;
background: #fff;
}
.mui-input-row label ~ input,
.mui-input-row label ~ select,
.mui-input-row label ~ textarea {
width: 78%;
}
.link-area {
display: block;
margin-top: 25px;
text-align: center;
}
.mui-content-padded {
margin-top: 30px;
}
</style>
3.实现登录功能
src\pages\user\Login.vue
login () {
if (this.loginForm.username === '' || this.loginForm.password === ''){
this.$toast('账号或密码不能为空')
} else {
this.$http.post('login', this.loginForm).then(res => {
if (res.data.code === 0) {
this.$toast(res.data.msg)
} else {
// 登录成功
}
}).catch(() => {
this.$toast('登录失败')
})
}
}
登录成功以后,将用户信息通过store保存。
src\store\modules\user.js
const state = {
id: 0,
username: ''
}
const getters = {}
const actions = {}
const mutations = {
setUser (state, user) {
state.id = user.id
state.username = user.username
}
}
export default {
namespaced: true,
state,
getters,
actions,
mutations
}
src\store\index.js
import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
user
}
})
src\pages\user\Login.vue
// 登录成功
this.$store.commit('user/setUser', res.data.data)
this.$toast(res.data.msg)
this.$router.replace({ name: 'user' })
判断是否已经登录
src\store\modules\user.js
const getters = {
isLogin (state) {
return state.id !== 0
}
}
src\pages\User.vue
<script>
import { mapGetters, mapState } from 'vuex'
export default {
computed: {
...mapState({
username: state => state.user.username
}),
...mapGetters('user', { isLogin: 'isLogin' })
}
}
</script>
<template>
<!-- 已登录 -->
<div v-if="isLogin">
<div class="member">
<div class="header-con">
<div class="user-info">
<div class="avatar-con">
<div class="avatar">
<img src="../assets/images/avatar_default.png" class="image-info">
</div>
</div>
<div class="person-con">
<span>{{ username }}</span>
</div>
</div>
</div>
</div>
</div>
<!-- 未登录 -->
<div v-else>
<div class="member">
……(原有代码)
</div>
</div>
</template>
4.登录接口和浏览器允许跨域
1、确保后台tpadmin项目安装部署正常,API接口可用
2、设置chrome浏览器,允许跨域访问。新版chrome浏览器的跨域设置(版本号49起):
在chrome浏览器属性页面中的“目标”输入框里加上:
--disable-web-security --user-data-dir=C:\MyChromeDevUserData
- 点击应用和确定后关闭属性页面,并打开 chrome 浏览器。发现有“--disable-web-security”相关的提示,说明 chrome 已经可以正常跨域工作了。
- 测试登录效果
未登录效果:
已登录效果:(用户名test,密码123456)
5.记住登录状态
登录成功以后,记住登录状态
src\auth.js
var auth = {
getAuthorization () {
return localStorage.getItem('Authorization');
},
setAuthorization (Authorization) {
localStorage.setItem('Authorization', Authorization);
}
}
export default {
install: function (vue) {
vue.prototype.$auth = auth
}
}
添加到src\main.js
Vue.config.productionTip = false
import auth from './auth.js'
Vue.use(auth)
import axios from './axios.js'
Vue.use(axios)
注意一定要在axios前面引入auth。
src\pages\user\Login.vue
// 登录成功
this.$store.commit('user/setUser', res.data.data)
this.$auth.setAuthorization(res.data.data.session_id)
this.$toast(res.data.msg)
this.$router.replace({ name: 'user' })
src\axios.js
将保存的session_id放入到下次请求的header中。
export default {
install: function (vue) {
var auth = vue.prototype.$auth
var obj = axios.create({
baseURL: config.baseURL
})
obj.interceptors.request.use(function (conf) {
conf.headers.Authorization = auth.getAuthorization()
return conf
})
vue.prototype.$http = obj
}
}
在下次刷新后,获取已登录的用户信息。
将代码写在src\App.vue中。
created () {
this.showBack = this.$route.path !== '/home'
this.checkLogin()
},
methods: {
goBack() {
this.$router.go(-1)
},
checkLogin() {
this.$indicator.open({
text: '加载中'
})
this.$http.get('user').then(res => {
if (res.data.code === 1) {
this.$store.commit('user/setUser', res.data.data)
}
this.$indicator.close()
})
}
},
访问测试。
重新登录用户,观察在页面刷新后,是否能够自动进行登录。
6.用户菜单
找到已登录的代码。
src\pages\User.vue
<!-- 已登录 -->
<div v-if="isLogin">
<div class="member">
……(原有代码)
</div>
<ul class="mui-table-view mui-table-view-chevron">
<li class="mui-table-view-cell mui-media">
<div class="mui-navigate-right">
<img class="mui-media-object mui-pull-left" src="../assets/images/avatar_default.png" />
<div class="mui-media-body">我的订单</div>
</div>
</li>
<li class="mui-table-view-cell mui-media">
<div class="mui-navigate-right">
<img class="mui-media-object mui-pull-left" src="../assets/images/avatar_default.png" />
<div class="mui-media-body">收货地址</div>
</div>
</li>
<li class="mui-table-view-cell mui-media">
<div class="mui-navigate-right">
<img class="mui-media-object mui-pull-left" src="../assets/images/avatar_default.png" />
<div class="mui-media-body">退出登录</div>
</div>
</li>
</ul>
</div>
样式:
<style lang="scss" scoped>
.mui-table-view .mui-media,
.mui-table-view .mui-media-body {
line-height: 42px;
}
.mui-table-view-cell:after {
left: 0px;
}
……(原有代码)
</style>
效果:
7.退出登录
src\pages\User.vue
<div @click="logout" class="mui-navigate-right">
<img class="mui-media-object mui-pull-left" src="../assets/images/avatar_default.png">
<div class="mui-media-body">退出登录</div>
</div>
export default {
computed: {
...mapState({
username: state => state.user.username
}),
...mapGetters('user', {
isLogin: 'isLogin'
})
},
methods: {
logout () {
this.$http.get('logout')
this.$store.commit('user/logout')
this.$auth.setAuthorization('')
this.$toast('退出成功')
}
}
}
src\store\modules\user.js
const mutations = {
……(原有代码)
logout (state) {
state.id = 0
state.username = ''
}
}
服务测试,当单击“退出登录”以后,页面会变成未登录的状态:
7.注册页面
注册路由:
src\router.js
import Register from './pages/user/Register.vue'
routes: [
……(原有代码)
{ path: '/user/register', component: Register, name: 'register', meta: { title: '注册' } }
],
src\pages\user\Register.vue
<template>
<div>
<div class="mui-content">
<form class="mui-input-group">
<div class="mui-input-row">
<label>账号</label>
<input v-model="regForm.username" type="text" class="mui-input-clear mui-input" placeholder="请输入账号">
</div>
<div class="mui-input-row">
<label>密码</label>
<input v-model="regForm.password" type="password" class="mui-input-clear mui-input" placeholder="请输入密码">
</div>
<div class="mui-input-row">
<label>确认</label>
<input type="password" ref="pwdConfirm" class="mui-input-clear mui-input" placeholder="请确认密码">
</div>
<div class="mui-input-row">
<label>邮箱</label>
<input v-model="regForm.email" type="email" class="mui-input-clear mui-input" placeholder="请输入邮箱">
</div>
</form>
<div class="mui-content-padded">
<button @click="register" class="mui-btn mui-btn-block mui-btn-primary">注册</button>
</div>
<div class="mui-content-padded">
<p>注册成功后的用户可用于登录</p>
</div>
</div>
</div>
</template>
数据绑定:
<script>
export default {
data () {
return {
regForm: {
username: '',
password: '',
email: ''
}
}
},
methods: {
register: function () {
}
}
}
</script>
样式:
<style lang="scss" scoped>
.mui-input-group {
margin-top: 10px;
background-color: transparent;
}
.mui-input-group label {
width: 22%;
}
.mui-input-row:last-child {
background: #fff;
}
.mui-input-row {
margin-top: 20px;
background: #fff;
}
.mui-input-row label ~ input,
.mui-input-row label ~ select,
.mui-input-row label ~ textarea {
width: 78%;
}
.link-area {
display: block;
margin-top: 25px;
text-align: center;
}
.mui-content-padded {
margin-top: 30px;
}
</style>
访问测试:
提交表单
register: function () {
var pwdConfirm = this.$refs.pwdConfirm.value
if (this.regForm.username === '') {
this.$toast('账号不能为空')
return
} else if (this.regForm.password === '') {
this.$toast('密码不能为空')
return
} else if (this.regForm.password != pwdConfirm) {
this.$toast('密码两次输入不一致')
return
} else if (this.regForm.email === '') {
this.$toast('邮箱不能为空')
return
}
console.log(this.regForm)
}
控制台输出结果:
8.注册接口
确保后台tpadmin项目安装部署正常,API接口可用
9.实现注册功能
提交注册表单:
src\pages\user\Register.vue
console.log(this.regForm)
this.$indicator.open({
text: '注册中'
})
this.$http.post('register', this.regForm).then(res => {
this.$indicator.close()
if (res.data.code === 0) {
this.$toast(res.data.msg)
} else {
this.$store.commit('user/setUser', res.data.data)
this.$auth.setAuthorization(res.data.data.session_id)
this.$toast(res.data.msg)
this.$router.replace({ name: 'user' })
}
}).catch(() => {
this.$toast('注册失败')
})
访问测试:
输入用户名和密码,点击注册。
注册完成后: