開始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%; width: 100%; } .loginPage{ height: 100%; width: 100%; background-image: linear-gradient(-180deg, #324157 38%, #00DEFF 100%); display: flex; align-items: center; justify-content: center; } .loginForm{ width: 30%; } .loginInput { margin: 10px 0; } .loginBtn { width: 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