开始coding啦
¶分析项目
根据展示效果我们可以分析出,Web页面有两个,一个用于登录,一个用于系统内容控制,我们分别将其命名为Login和Cms,然后进行路由配置。
- 在src/page下新建Login.vue和Cms.vue文件,及进行vue模板构建
|--src
|--page
|--Cms.vue
|--Login.vue
<template>
</template>
<script scope>
</script>
<style>
</style>
-
将Login和Cms组件导入到/router/index.js中
// import something.... import Cms from '@/page/Cms' import Login from '@/page/Login'
-
修改路由配置,该配置在/src/router/index.js中;将如下代码
routes: [ { path: '/', name: 'Hello', component: Hello } ]
修改为
routes: [ { path: '/cms', // 后台管理系统路由 name: 'Cms', component: Cms }, { path: '/', // 登录路由 name: 'Login', component: Login } ]
¶内容实现
-
登录请求存储
我们将登录状态存储在sessionStorage中,所以在/src下新建utils/index.js,并写入如下代码
let KEY = 'USER' export default { /** * set user info in sessionStorage * @param userInfo Object user info * @return none */ setLoginState: (userInfo) => { window.sessionStorage.setItem(KEY, JSON.stringify(userInfo)) }, /** * get user info from sessionStorage * @return userInfo Object user Info */ getLoginState: () => { return window.sessionStorage.getItem(KEY) }, deleteLoginState: () => { return new Promise((resolve, reject) => { window.sessionStorage.removeItem(KEY) ? resolve({'isDelete': true}) : reject({'isDelete': false}) }) } }
-
整合Axios请求
向后台请求数据,必须有像Ajax一样的请求,幸好在Node环境下有Axios这样的npm库封装了xhr这样的请求,这个库在上一节已经完成安装,为了在本系统中使用,且符合Vue开发规范,我们将其再次进行封装;在src目录下新建api/index.js文件,并写入如下代码
// 配置API接口地址 var root = '/api/v1' // 引用axios var axios = require('axios') // 自定义判断元素类型JS function toType (obj) { return ({}).toString.call(obj).match(/s([a-zA-Z]+)/)[1].toLowerCase() } // 参数过滤函数 function filterNull (o) { for (var key in o) { if (o[key] === null) { delete o[key] } if (toType(o[key]) === 'string') { o[key] = o[key].trim() } else if (toType(o[key]) === 'object') { o[key] = filterNull(o[key]) } else if (toType(o[key]) === 'array') { o[key] = filterNull(o[key]) } } return o } /* 接口处理函数 这个函数每个项目都是不一样的,我现在调整的是适用于 https://cnodejs.org/api/v1 的接口,如果是其他接口 需要根据接口的参数进行调整。参考说明文档地址: https://cnodejs.org/topic/5378720ed6e2d16149fa16bd 主要是,不同的接口的成功标识和失败提示是不一致的。 另外,不同的项目的处理方法也是不一致的,这里出错就是简单的alert */ function apiAxios (method, url, params, success, failure) { if (params) { params = filterNull(params) } axios({ method: method, url: url, data: method === 'POST' || method === 'PUT' ? params : null, params: method === 'GET' || method === 'DELETE' ? params : null, baseURL: root, withCredentials: false }) .then(function (res) { if (res.data.success === true) { if (success) { success(res.data) } } else { if (failure) { failure(res.data) } else { window.alert('error: ' + JSON.stringify(res.data)) } } }) .catch(function (err) { let res = err.response if (err) { window.alert('api error, HTTP CODE: ' + res.status ? res.status : null) return } }) } // 返回在vue模板中的调用接口 export default { get: function (url, params, success, failure) { return apiAxios('GET', url, params, success, failure) }, post: function (url, params, success, failure) { return apiAxios('POST', url, params, success, failure) }, put: function (url, params, success, failure) { return apiAxios('PUT', url, params, success, failure) }, delete: function (url, params, success, failure) { return apiAxios('DELETE', url, params, success, failure) } }
-
登录Login.vue组件实现
因为写的Vue不是纯Js,所以代码木有高亮
<template> <div class='login'> <div class='loginPage' > <el-form class='loginForm' label-position='left' label-width="80px" > <el-input class='loginInput' placeholder="请输入内容" @change='usernameChange' > <template slot="prepend">用户名</template> </el-input> <el-input class='loginInput' type='password' placeholder="请输入内容" @change='userPassChange' > <template slot="prepend">密码</template> </el-input> <el-button class='loginBtn' type="primary" :disabled="isLoginBtnDisable" @click='login'>登录</el-button> </el-form> </div> <cms-footer :siteInfo='siteinfo'></cms-footer> </div> </template> <script> import CmsFooter from '../components/Footer' export default { data () { return { isLoginBtnDisable: true, username: null, userPass: null, siteinfo: { name: '', title: '', logo: '', copyright: '' } } }, components: { 'cms-footer': CmsFooter }, created () { this.getSiteInfo() }, methods: { refresh () { window.location.reload() }, login (evt) { if (!this.isLoginBtnDisable) { let params = { account: this.username, password: this.userPass } this.$api.post('login', params, (errObj) => { console.log('login error', JSON.stringify(errObj)) }, (resp) => { resp && resp.code === 0 ? this.setUserInfoToGo({account: this.username}) : null }) } }, setUserInfoToGo (userInfo) { this.$utils.setLoginState(userInfo) this.$router.push('/cms') }, usernameChange (evt) { // evt ? this.username = evt && this.userPass ? this.isLoginBtnDisable = true && console.log(this.isLoginBtnDisable) : this.isLoginBtnDisable = false : this.username = null if (evt) { this.username = evt this.userPass ? this.isLoginBtnDisable = false : this.isLoginBtnDisable = true } else { this.username = null this.isLoginBtnDisable = true } }, userPassChange (evt) { // evt ? this.userPass = evt && this.username ? this.isLoginBtnDisable = true : this.isLoginBtnDisable = false : this.userPass = null if (evt) { this.userPass = evt this.username ? this.isLoginBtnDisable = false : this.isLoginBtnDisable = true } else { this.userPass = null this.isLoginBtnDisable = true } }, getSiteInfo () { let _self = this _self.$api.get('site', null, (er) => {}, (res) => { if (res.code === 0) { _self.siteinfo = res.data _self.$compUtils.setSiteInfo(res.data) } }) } } } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> .login{ height: 100%; 100%; } .loginPage{ height: 100%; 100%; background-image: linear-gradient(-180deg, #324157 38%, #00DEFF 100%); display: flex; align-items: center; justify-content: center; } .loginForm{ 30%; } .loginInput { margin: 10px 0; } .loginBtn { 100%; } </style>
-
效果
)
¶总结
在登录组件中,我们封装了Axios,将其根据web请求(put、post、get和delete)形成统一的请求接口;在登录时向后台请求并完成登录信息在SessionStorage中存储及路由跳转。需要注意的是vue官方建议tab是2格,不然其Eslint会报错,编译不通过。
// codes
setUserInfoToGo (userInfo) {
this.$utils.setLoginState(userInfo)
this.$router.push('/cms')
}
// codes