基于VUE实现的新闻后台管理系统-三

简介: 开始coding啦¶分析项目根据展示效果我们可以分析出,Web页面有两个,一个用于登录,一个用于系统内容控制,我们分别将其命名为Login和Cms,然后进行路由配置。在src/page下新建Login.

开始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>
  2. 将Login和Cms组件导入到/router/index.js中

    // import something....
    import Cms from '@/page/Cms'
    import Login from '@/page/Login'
  3. 修改路由配置,该配置在/src/router/index.js中;将如下代码

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

    修改为

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

    ¶内容实现

  4. 登录请求存储

    我们将登录状态存储在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})
            })
        }
        }
  5. 整合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)
    }
    }
  6. 登录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>
  7. 效果
    login
    )

    ¶总结

    在登录组件中,我们封装了Axios,将其根据web请求(put、post、get和delete)形成统一的请求接口;在登录时向后台请求并完成登录信息在SessionStorage中存储及路由跳转。需要注意的是vue官方建议tab是2格,不然其Eslint会报错,编译不通过。

    // codes
    setUserInfoToGo (userInfo) {
      this.$utils.setLoginState(userInfo)
      this.$router.push('/cms')
    }
    // codes
目录
相关文章
|
5天前
|
资源调度 JavaScript 前端开发
【vue】vue中的路由vue-router,vue-cli脚手架详细使用教程
【vue】vue中的路由vue-router,vue-cli脚手架详细使用教程
|
5天前
|
JavaScript
【vue】深入探讨vue中组件间多种传值方式
【vue】深入探讨vue中组件间多种传值方式
【vue】深入探讨vue中组件间多种传值方式
|
5天前
|
JavaScript 前端开发
vue组件化开发流程梳理,拿来即用
vue组件化开发流程梳理,拿来即用
|
5天前
|
移动开发 JavaScript 前端开发
Vue Router的介绍与引入
Vue Router的介绍与引入
|
5天前
|
JavaScript 应用服务中间件 nginx
vue中404解决方法
vue中404解决方法
|
9天前
|
JavaScript
【vue】如何跳转路由到指定页面位置
【vue】如何跳转路由到指定页面位置
13 0
|
9天前
|
资源调度 JavaScript 前端开发
【vue】vue-cli版本选择和比较(vue-cli3.0新版本如何创建项目)
【vue】vue-cli版本选择和比较(vue-cli3.0新版本如何创建项目)
17 1
|
9天前
|
JavaScript 前端开发
【vue】iview如何把input输入框和点击输入框之后的边框去掉
【vue】iview如何把input输入框和点击输入框之后的边框去掉
15 0
|
9天前
|
JavaScript UED
【vue】iview组件 DatePicker 日期选择器如何显示默认当前日期
【vue】iview组件 DatePicker 日期选择器如何显示默认当前日期
13 1
|
5天前
|
JavaScript
Vue 中如何模块化使用 Vuex
Vue 中如何模块化使用 Vuex