• ElementUI之首页导航+左侧菜单


    一、Mock.js

    1.1.什么是Mock.js

    前后端分离开发开发过程当中,经常会遇到以下几个尴尬的场景:

    • 老大,接口文档还没输出,我的好多活干不下去啊!
    • 后端小哥,接口写好了没,我要测试啊!

    前后端分离之后,前端迫切需要一种机制,不再需要依赖后端接口开发,而今天的主角mockjs就可以做到这一点。

    Mock.js是一个模拟数据的生成器,用来帮助前端调试开发、进行前后端的原型分离以及用来提高自动化测试效率。

    众所周知Mock.js因为两个重要的特性风靡前端:

    • 数据类型丰富:支持生成随机的文本、数字、布尔值、日期、邮箱、链接、图片、颜色等。
    • 拦截Ajax请求:不需要修改既有代码,就可以拦截Ajax请求,返回模拟的响应数据。

    1.2.安装与配置

    npm i mockjs -D 
    
    • 1

    为了只在开发环境使用mock,而打包到生产环境时自动不使用mock,我们可以在config目录中的dev.env.js和prod.env.js做一个配置,如下:

    • dev.env.js
     module.exports = merge(prodEnv, {
      NODE_ENV: '"development"',
    	MOCK: 'true'
    })
    
    • 1
    • 2
    • 3
    • 4
    • prod.env.js
     module.exports = {
      NODE_ENV: '"production"',
    	MOCK: 'false'
    }
    
    • 1
    • 2
    • 3
    • 4
    • main.js
     //开发环境下才会引入mockjs
    process.env.MOCK && require('@/mock') 
    
    • 1
    • 2

    1.3使用

    创建mock目录,mock下创建index.js以及json文件夹,在JSON文件夹中创建login-mock.js

    • index.js 将mock与url绑定
    import Mock from 'mockjs' //引入mockjs,npm已安装
    import action from '@/api/action' //引入请求地址
    
    
    //全局设置:设置所有ajax请求的超时时间,模拟网络传输耗时
    Mock.setup({
    	// timeout: 400  //延时400ms请求到数据
    	timeout: 200 - 400 //延时200-400ms请求到数据
    })
    
    //引登陆的测试数据,并添加至mockjs
    import loginInfo from '@/mock/json/login-mock.js'
    let s1 = action.getFullPath('SYSTEM_USER_DOLOGIN')
    Mock.mock(s1, "post", loginInfo)
    // Mock.mock(s1, /post|get/i, loginInfo)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • login-lock.js code随机0或-1,msg随机3-10个’msg’
    //使用mockjs的模板生成随机数据
    const loginInfo = {
    	'code|-1-0': 0,
    	'message|3-10': 'msg'
    }
    export default loginInfo;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 修改Login.vue中的doSubmit()的内容
    doSubmit: function () {
        let params = {
            username: this.username,
            password: this.password
        };
        console.log(params);
        let url = this.axios.urls.SYSTEM_USER_DOLOGIN;
        this.axios.post(url, params).then(response => {
            console.log(response);
            if (response.data.code == 0) {
                this.$message({
                    message: response.data.message,
                    type: 'success'
                })
            } else {
                this.$message({
                    message: response.data.message,
                    type: 'error'
                })
            }
        }).catch(error => {
            console.log(error);
        });
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    在这里插入图片描述

    二、登录注册跳转

    使用this.$router.push({})

    2.1.在views中添加Register.vue

    <template>
      <div class="login-wrap">
        <el-form class="login-container">
          <h1 class="title">用户注册h1>
          <el-form-item label="">
            <el-input type="text" v-model="username" placeholder="登录账号" autocomplete="off">el-input>
          el-form-item>
          <el-form-item label="">
            <el-input type="password" v-model="password" placeholder="登录密码" autocomplete="off">el-input>
          el-form-item>
          <el-form-item>
            <el-button type="primary" style="width:100%;" @click="doSubmit()">提交el-button>
          el-form-item>
          <el-row style="text-align: center;margin-top:-10px">
            <el-link type="primary">忘记密码el-link>
            <el-link type="primary" @click="gotoLogin()">用户登录el-link>
          el-row>
        el-form>
      div>
    template>
    
    <script>
    
    export default {
      name: 'Login',
      data: function () {
        return {
          username: "admin",
          password: "123"
        }
      },
      methods: {
        doSubmit: function () {
    
        },
        gotoLogin(){
          this.$router.push({path: '/'})
        }
      }
    }
    script>
    
    <style scoped>
    .login-wrap {
      box-sizing: border-box;
      width: 100%;
      height: 100%;
      padding-top: 10%;
      /* background-color: #112346; */
      background-repeat: no-repeat;
      background-position: center right;
      background-size: 100%;
    }
    
    .login-container {
      border-radius: 10px;
      margin: 0px auto;
      width: 350px;
      padding: 30px 35px 15px 35px;
      background: #fff;
      border: 1px solid #eaeaea;
      text-align: left;
      box-shadow: 0 0 20px 2px rgba(0, 0, 0, 0.1);
    }
    
    .title {
      margin: 0px auto 40px auto;
      text-align: center;
      color: #505458;
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71

    2.2.在Login.vue中的methods中添加gotoRegister方法

    gotoRegister(){
        this.$router.push({path: '/register'})
    }
    
    • 1
    • 2
    • 3

    2.3.在router/index.js中注册路由

    import Register from '@/views/Register'
    
    //以下内容添加到routes中
    {
    	path: '/register',
    	name: 'Register',
    	component: Register
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

    三、组件通信(总线)

    在这里插入图片描述

    3.1 在main.js中添加内容

    //在new Vue中添加
    data(){
      return{
          Bus: new Vue({})
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3.2.在components中添加内容

    • AppMain.vue
    <template>
      <el-container class="main-container">
        <el-aside v-bind:class="asideClass">
          <LeftNav>LeftNav>
        el-aside>
        <el-container>
          <el-header class="main-header">
            <TopNav>TopNav>
          el-header>
          <el-main class="main-center">Mainel-main>
        el-container>
      el-container>
    template>
    
    <script>
    // 导入组件
    import TopNav from '@/components/TopNav.vue'
    import LeftNav from '@/components/LeftNav.vue'
    
    // 导出模块
    export default {
    	
      components: {LeftNav, TopNav},
      data() {
        return {
          asideClass: 'main-aside'
        }
      },
      created() {
        this.$root.Bus.$on('doCollapsed', v => {
          //v指的是topNav传递过来的this.collapsed
          this.asideClass = v ? 'main-aside-collapsed' : 'main-aside';
        });
      }
    };
    script>
    <style scoped>
    .main-container {
      height: 100%;
      width: 100%;
      box-sizing: border-box;
    }
    
    .main-aside-collapsed {
      /* 在CSS中,通过对某一样式声明! important ,可以更改默认的CSS样式优先级规则,使该条样式属性声明具有最高优先级 */
      width: 64px !important;
      height: 100%;
      background-color: #334157;
      margin: 0px;
      transition: width 0.6s ease;
    }
    
    .main-aside {
      width: 240px !important;
      height: 100%;
      background-color: #334157;
      margin: 0px;
      transition: width 0.6s ease;
    }
    
    .main-header,.main-center {
      padding: 0px;
      border-left: 2px solid #333;
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • TopNav.vue
    
    <template>
      
      <el-menu class="el-menu-demo" mode="horizontal" background-color="#334157" text-color="#fff" active-text-color="#fff">
        <el-button class="buttonimg">
          <img class="showimg" :src="collapsed?imgshow:imgsq" @click="doToggle()">
        el-button>
        <el-submenu index="2" class="submenu">
          <template slot="title">超级管理员template>
          <el-menu-item index="2-1">设置el-menu-item>
          <el-menu-item index="2-2">个人中心el-menu-item>
          <el-menu-item @click="exit()" index="2-3">退出el-menu-item>
        el-submenu>
      el-menu>
    template>
    
    <script>
    export default {
      data() {
        return {
          collapsed: false,
          imgshow: require('@/assets/img/show.png'),
          imgsq: require('@/assets/img/sq.png')
        }
      }, methods: {
        doToggle() {
          this.collapsed = !this.collapsed;
          this.$root.Bus.$emit('doCollapsed', this.collapsed);
        },
        exit(){
          this.$router.push({path:'/'})
        }
      }
    }
    script>
    
    <style scoped>
    .el-menu-vertical-demo:not(.el-menu--collapse) {
      border: none;
    }
    
    .submenu {
      float: right;
    }
    
    .buttonimg {
      height: 60px;
      background-color: transparent;
      border: none;
    }
    
    .showimg {
      width: 26px;
      height: 26px;
      position: absolute;
      top: 17px;
      left: 17px;
    }
    
    .showimg:active {
      border: none;
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • LeftNav.vue
    
    <template>
      <el-menu default-active="2" class="el-menu-vertical-demo" background-color="#334157"
               text-color="#fff" active-text-color="#ffd04b" :collapse="collapsed">
        
        <div class="logobox">
          <img class="logoimg" src="../assets/img/logo.png" alt="">
        div>
        <el-submenu index="1">
          <template slot="title">
            <i class="el-icon-location">i>
            <span>导航一span>
          template>
          <el-menu-item-group>
            <template slot="title">分组一template>
            <el-menu-item index="1-1">选项1el-menu-item>
            <el-menu-item index="1-2">选项2el-menu-item>
          el-menu-item-group>
          <el-menu-item-group title="分组2">
            <el-menu-item index="1-3">选项3el-menu-item>
          el-menu-item-group>
          <el-submenu index="1-4">
            <template slot="title">选项4template>
            <el-menu-item index="1-4-1">选项1el-menu-item>
          el-submenu>
        el-submenu>
        <el-menu-item index="2">
          <i class="el-icon-menu">i>
          <span slot="title">导航二span>
        el-menu-item>
        <el-menu-item index="3" disabled>
          <i class="el-icon-document">i>
          <span slot="title">导航三span>
        el-menu-item>
        <el-menu-item index="4">
          <i class="el-icon-setting">i>
          <span slot="title">导航四span>
        el-menu-item>
      el-menu>
    template>
    <script>
    export default {
      data() {
        return {
          collapsed: false
        }
      },
      created() {
        this.$root.Bus.$on('doCollapsed', v => {
            //v指的是topNav传递过来的this.collapsed
          this.collapsed = v;
        });
      }
    }
    script>
    <style>
    .el-menu-vertical-demo:not(.el-menu--collapse) {
      width: 240px;
      min-height: 400px;
    }
    
    .el-menu-vertical-demo:not(.el-menu--collapse) {
      border: none;
      text-align: left;
    }
    
    .el-menu-item-group__title {
      padding: 0px;
    }
    
    .el-menu-bg {
      background-color: #1f2d3d !important;
    }
    
    .el-menu {
      border: none;
    }
    
    .logobox {
      height: 40px;
      line-height: 40px;
      color: #9d9d9d;
      font-size: 20px;
      text-align: center;
      padding: 20px 0px;
    }
    
    .logoimg {
      height: 40px;
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91

    3.3.在router/index.js中配置路由

    {
    		path: '/appMain',
    		name: 'AppMain',
    		component: AppMain,
    		children: [{
    				path: '/TopNav',
    				name: 'TopNav',
    				component: TopNav
    			},{
    				path: '/leftNav',
    				name: 'LeftNav',
    				component: LeftNav
    	        }
    		]
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    4.登出

    • 修改topNav的内容
    //在methods中添加exit()方法
    exit(){
    	this.$router.push({path:'/login'})
    }
    
    • 1
    • 2
    • 3
    • 4
  • 相关阅读:
    ZooKeeper面试那些事儿
    Python学生公寓管理系统的设计与实现毕业设计源码181047
    专访 | 许伟 ——贡献榜 Top4 也只是“开源小白”
    Java多线程篇(12)——ForkJoinPool
    Java EE改名Jakarta EE,jakarta对程序开发的影响
    【.NET】快速入门
    SpringBoot中yml文件key值不匹配,引发的空指针异常解决办法
    CommonsCollections4利用链分析
    Elasticsearch:使用反向地理编码在地图上显示自定义区域统计数据
    发现 Cargo 的魅力:优雅地构建、发布和管理 Rust 项目
  • 原文地址:https://blog.csdn.net/TestXzing/article/details/133299146