基於VUE實現的新聞后台管理系統-三


開始coding啦

¶分析項目

根據展示效果我們可以分析出,Web頁面有兩個,一個用於登錄,一個用於系統內容控制,我們分別將其命名為Login和Cms,然后進行路由配置。

  1. 在src/page下新建Login.vue和Cms.vue文件,及進行vue模板構建

|--src
    |--page
        |--Cms.vue
        |--Login.vue

<template>
</template>
<script scope>
</script>
<style>
</style>
  1. 將Login和Cms組件導入到/router/index.js中

    // import something....
    import Cms from '@/page/Cms'
    import Login from '@/page/Login'
    
  2. 修改路由配置,該配置在/src/router/index.js中;將如下代碼

    routes: [
        {
        path: '/',
        name: 'Hello',
        component: Hello
        }
    ]
    

    修改為

    routes: [
        {
        path: '/cms', // 后台管理系統路由
        name: 'Cms',
        component: Cms
        },
        {
        path: '/', // 登錄路由
        name: 'Login',
        component: Login
        }
    ]
    

¶內容實現

  1. 登錄請求存儲

    我們將登錄狀態存儲在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})
            })
        }
        }
    
  2. 整合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)
    }
    }
    
    
  3. 登錄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>
    
  4. 效果
    login
    )

¶總結

在登錄組件中,我們封裝了Axios,將其根據web請求(put、post、get和delete)形成統一的請求接口;在登錄時向后台請求並完成登錄信息在SessionStorage中存儲及路由跳轉。需要注意的是vue官方建議tab是2格,不然其Eslint會報錯,編譯不通過。

// codes
setUserInfoToGo (userInfo) {
  this.$utils.setLoginState(userInfo)
  this.$router.push('/cms')
}
// codes


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM