登录页面 引用ElementUI
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on"
label-position="left">
<h3 class="title">xx标题xx</h3>
<el-form-item prop="username">
<span class="svg-container">
<svg-icon icon-class="user"/><!-- 这里用了svg组件 封装一下icon -->
</span>
<el-input v-model="loginForm.username" name="username" type="text" auto-complete="on" placeholder="用户名"/>
</el-form-item>
<el-form-item prop="password">
<span class="svg-container">
<svg-icon icon-class="password"/>
</span>
<el-input
:type="pwdType"
v-model="loginForm.password"
name="password"
auto-complete="on"
placeholder="密码"/>
<span class="show-pwd" @click="showPwd">
<svg-icon :icon-class="pwdType === 'password' ? 'eye' : 'eye-open'"/>
</span>
</el-form-item>
<el-form-item prop="verification">
<span class="svg-container">
<svg-icon icon-class="verification"/>
</span>
<el-input v-model="loginForm.verification" name="verification" type="text" auto-complete="on"
placeholder="验证码" maxlength="4"
@keyup.enter.native="handleLogin"/><!-- 监听键盘回车事件 -->
</el-form-item>
<el-form-item>
<el-button :loading="loading" type="primary" style="width:100%;background-color: #1EAE1D;border: none"
@click.native.prevent="handleLogin">
登录
</el-button>
</el-form-item>
</el-form>
data() {
const validateUsername = (rule, value, callback) => {
if (!value) {
callback(new Error('请输入正确的用户名'))
} else {
callback()
}
}
},
const validatePass = (rule, value, callback) => {
if (value.length < 5) {
callback(new Error('密码不能小于5位'))
} else {
callback()
}
}
const validateVerifi = (rule, value, callback) => {
if (value.length < 4) {
callback(new Error('验证码不能小于4位'))
} else {
callback()
}
},
return {
loginRules: {
username: [{required: true, trigger: 'blur', validator: validateUsername}],
password: [{required: true, trigger: 'blur', validator: validatePass}],
verification: [{required: true, trigger: 'blur', validator: validateVerifi}]
},
loading: false,
pwdType: 'password',
redirect: undefined
},
watch: {//监听路由 有两个参数
$route: {
handler: function (route) {
this.redirect = route.query && route.query.redirect
},
immediate: true //立即执行
}
},
methods: {
showPwd() {
if (this.pwdType === 'password') {
this.pwdType = ''
} else {
this.pwdType = 'password'
}
}
,
handleLogin() {
this.$refs.loginForm.validate(valid => {
//会验证该form所有字段的返回值,如果有不通过的valid就是false
if (valid) {
this.loading = true
//表单提交 触发指定事件 (路由拦截 response,request设置每个请求携带自定义token)
this.$store.dispatch('Login', this.loginForm).then(() => {
this.loading = false
this.$router.push({path: this.redirect || '/'})
}).catch(() => {
this.loading = false
})
} else {
return false
}
})
}
},
// store 登录 引入vue,vuex(Vue.use(Vuex))
const getters = {//获取到用户状态,实时监听state值的变化
token: state => state.user.token,
}
const storeUser = {
state: {
token: "_token"
},
mutations: {
SET_TOKEN: (state, token) => {//自定义初始值
state.token = token
},
},
actions: {//异步触发mutations里面的方法,userInfo为页面传过来的值
//登录
Login({commit}, userInfo) {
const username = userInfo.username.trim()
return new Promise((resolve, reject) => {
//api 单独的组件login
login(username, userInfo.password, userInfo.verification).then(response => {
const data = response.data
//设置token
setToken(data.token)
commit('SET_TOKEN', data.token)
resolve()
}).catch(error => {
reject(error)
})
})
},
}
}
const store = new Vuex.Store({
modules: {
storeUser
},
getters
})
export default store
svg-icon 参考张鑫旭大大的文章未来必热:SVG Sprite技术介绍
//引入axios 创建axios实例
var instance = axios.create({
baseURL: 'https://some-domain.com/api/',
timeout: 1000,
//headers: {'X-Custom-Header': 'foobar'}
});
// 添加请求拦截器
instance.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
config.headers['X-Custom-Header'] = 'foobar' // 让每个请求携带自定义token
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
instance.interceptors.response.use(function (response) {
// 对响应数据做点什么
return response;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
参考资料:axios中文文档