1.登录界面
登录界面主要就是两个输入框和一个登录框来组成.
1.静态页面
用户名的登录框只需要设置ref和v-modle即可。
<el-input
ref="username"
v-model="loginForm.username"
placeholder="Username"
name="username"
type="text"
tabindex="1"
auto-complete="on"
/>
密码的input框则需要加一个enter的keyup事件来进行登录。
<el-input
:key="passwordType"
ref="password"
v-model="loginForm.password"
:type="passwordType"
placeholder="Password"
name="password"
tabindex="2"
auto-complete="on"
@keyup.enter.native="handleLogin"
/>
密码框中的点击小眼睛
<span class="show-pwd" @click="showPwd">
<svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" />
</span>
2.data()
在data中所需要return的内容为:
return {
//初始的账号和密码,显示在input框中
loginForm: {
username: 'admin',
password: '111111'
},
//账号和密码的规则对象。
loginRules: {
username: [{ required: true, trigger: 'blur', validator: validateUsername }],
password: [{ required: true, trigger: 'blur', validator: validatePassword }]
},
loading: false,
//密码输入框的类型,所对应的key值。
passwordType: 'password',
//跳转的路由地址
redirect: undefined
}
其中对于账号和密码规则的函数如下。
const validateUsername = (rule, value, callback) => {
if (!validUsername(value)) { //如果用户名为空则弹出警告
callback(new Error('Please enter the correct user name'))
} else {
callback()
}
}
const validatePassword = (rule, value, callback) => {
if (value.length < 6) { //如果密码小于6位,就弹出警告
callback(new Error('The password can not be less than 6 digits'))
} else {
callback()
}
}
3.watch监听route变化
每次登录进来会进入上一次访问的界面,所以对于route要有个监听函数,将最新的路由地址给到redirect。
watch: {
$route: {
handler: function(route) {
this.redirect = route.query && route.query.redirect
},
immediate: true
}
},
4.methods方法
1. 密码框内容的显示与隐藏。
showPwd() {
if (this.passwordType === 'password') {
this.passwordType = '' //改变input的类型
} else {
this.passwordType = 'password'
}
this.$nextTick(() => {
this.$refs.password.focus() //获取到密码的焦点。
})
},
2. 登录方法:利用vuex访问接口
handleLogin() {
this.$refs.loginForm.validate(valid => { //通过表单验证
if (valid) {
this.loading = true
this.$store.dispatch('user/login', this.loginForm).then(() => {
this.$router.push({ path: this.redirect || '/' }) //路由跳转
this.loading = false
}).catch(() => {
this.loading = false
})
} else {
console.log('error submit!!')
return false
}
})
}
login的action:在store中的user.js
login({ commit }, userInfo) { //将loginForm传过来
const { username, password } = userInfo //在信息中将用户名和密码解构出来
return new Promise((resolve, reject) => {
login({ username: username.trim(), password: password }).then(response => { //login是配置的登录访问接口
const { data } = response
commit('SET_TOKEN', data.token)
setToken(data.token)
resolve()
}).catch(error => {
reject(error)
})
})
login的访问接口,在@/api/user.js
export function login(data) {
return request({
url: '/vue-admin-template/user/login',
method: 'post',
data
})
}
mutations中的SET_TOKEN如下:
const mutations = {
SET_TOKEN: (state, token) => {
state.token = token
}
}
这里的token是利用getToken()得到的。
const TokenKey = 'vue_admin_template_token'
export function getToken() {
return Cookies.get(TokenKey)
}
2.主页面
主界面是Layout组件,内部分成三部分,分别是侧边栏Sidebar,nav栏,和显示内容区app-main。
1.侧边栏Sidebar
侧边栏实际上是通过路由配置来实现的,有这么几个参数我们可以配置。
1.hidden:true:不显示在侧边栏,比如404,login这些。
{
path: '/404',
component: () => import('@/views/404'), //这里是用此类方法添加组件
hidden: true
},
2. redirect:面包屑不可被点击。
//当设置 noRedirect 的时候该路由在面包屑导航中不可被点击
redirect: 'noRedirect'
3.name
name: 'router-name' // 设定路由的名字,一定要填写不然使用<keep-alive>时会出现各种问题
4.meta
meta: {
roles: ['admin', 'editor'] // 设置该路由进入的权限,支持多个权限叠加
title: 'title' // 设置该路由在侧边栏和面包屑中展示的名字
icon: 'svg-name' // 设置该路由的图标,支持 svg-class,也支持 el-icon-x element-ui 的 icon
noCache: true // 如果设置为true,则不会被 <keep-alive> 缓存(默认 false)
breadcrumb: false // 如果设置为false,则不会在breadcrumb面包屑中显示(默认 true)
affix: true // 如果设置为true,它则会固定在tags-view中(默认 false)
// 当路由设置了该属性,则会高亮相对应的侧边栏。
// 这在某些场景非常有用,比如:一个文章的列表页路由为:/article/list
// 点击文章进入文章详情页,这时候路由为/article/1,但你想在侧边栏高亮文章列表的路由,就可以进行如下设置
activeMenu: '/article/list'
}
实际举例:
{
path: '/example',
component: Layout,
redirect: '/example/table',
name: 'Example',
meta: { title: 'Example', icon: 'el-icon-s-help' },
children: [
{
path: 'table',
name: 'Table',
component: () => import('@/views/table/index'),
meta: { title: 'Table', icon: 'table' }
},
{
path: 'tree',
name: 'Tree',
component: () => import('@/views/tree/index'),
meta: { title: 'Tree', icon: 'tree' }
}
]
},