ElementUI -- Introduction and use of Mock.js and construction of the left menu of the homepage navigation bar

1.1 Introduction to mockjs

        Mock.js is a JavaScript library for generating random data and mocking interface requests. It can help developers simulate the return data of the back-end interface during the front-end development process for the development and testing of front-end pages.

Mock.js has two important features that are popular in front-ends:

  • Rich data types

        Mock.js provides a simple and easy-to-use API that can be used to generate various types of random data, such as strings, numbers, Boolean values, dates, etc. Developers can use Mock.js to define the return data structure of an interface and generate random data that conforms to that structure.

  • Intercepting Ajax requests

        By intercepting Ajax requests, Mock.js can intercept requests sent by the front end and return mocked data according to predefined rules. The delayed response function can simulate network delays to test the performance of the page under different network conditions. The dynamic data generation function can generate qualified random data based on request parameters. You can intercept Ajax requests and return simulated response data without modifying existing code.
 

1.2 mock.js installation and configuration

1.2.1 Install mock.js

npm i mockjs -D

 I have already installed it here. I forgot to take a screenshot. It is still the same. Just enter the root directory of the project cmd and execute the command.

  • -S option is used to start the development server
  • -D option is used to automatically open the browser after starting the development server
  • The -G option is used to generate code or files. They are used for different development scenarios and needs, and the specific use depends on your goals and tasks.
1.2.2 Introduction of mock.js

In order to only use mocks in the development environment and automatically not use mocks when packaging to the production environment, we can make a configuration in the config directory, as followsdev.env.js : prod.env.js

  • dev.env.js: production environment

    'use strict'
    const merge = require('webpack-merge')
    const prodEnv = require('./prod.env')
    
    module.exports = merge(prodEnv, {
      NODE_ENV: '"development"',
      // 生产环境下使用mock
          MOCK:'true'
    })
    

  • prod.env.js: development environment

    'use strict'
    module.exports = {
      NODE_ENV: '"production"',
      // 打包环境下不使用mock
      MOCK:'false'
    }
    

  • main.js

    //开发环境下才会引入mockjs
    process.env.MOCK && require('@/mock') 

    After completing this step, our program will report an error, telling us that our mock module was not found under src. Don't worry, it will be defined below.

1.3 Use of mock.js

  • 1.3.1 Preparing simulation data

    Define a separate xxx-mock.js file for each *.vue and add custom json data to it. You can also generate random data information through the mockjs module to dynamically test the ajax request effect.

Create src/mock/jsona directory and define the login test data file login-mock.js:

//在没有使用mock.js前,定义数据的方式(死数据)
/* const loginInfo = {
  code: -1,
  message: '密码错误'
} */
 
//使用mockjs的模板生成随机数据
const loginInfo = {
  //1表示50%概率
  "success|1": true,
  //1-2指重复1到2次
  "msg|1-2": 'msg'
}
 
//将当前模块导出,导出后index.js才可以导入
export default loginInfo;
1.3.2 Define interception routes

Create a mock directory         in the src directory , define the mock main file index.js , and define the interception routing configuration in this file, /src/mock/index.js.

import Mock from 'mockjs' //引入mockjs,npm已安装
import action from '@/api/action' //引入请求地址
 
//全局设置:设置所有ajax请求的超时时间,模拟网络传输耗时
Mock.setup({
	// timeout: 400  //延时400s请求到数据
	timeout: 200 - 400 //延时200-400s请求到数据
})
 
//获取请求的url
let url = action.getFullPath('SYSTEM_USER_DOLOGIN');
//引登陆的测试数据,并添加至mockjs
import loginInfo from '@/mock/json/login-mock.js'
Mock.mock(url, "get", loginInfo)
 
//如果请求既可以是get又可以是post的请求方式可以使用如下方式:
// Mock.mock(s1, /post|get/i, loginInfo)
1.3.3 Testing

Edit the Login.vue file and give different prompts based on different responses.

<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="warning" 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="gotoRegister()">用户注册</el-link>
      </el-row>
    </el-form>
  </div>
</template>
 
<script>
  export default {
    name: 'Login',
    data() {
      return {
        username: '',
        password: ''
      }
    },
    methods: {
      gotoRegister() {
        this.$router.push("/Register");
      },
      doSubmit() {
        //定义后台登录方法连接地址
        let url = this.axios.urls.SYSTEM_USER_DOLOGIN;
        //获取数据
        let params = {
          username: this.username,
          password: this.password
        };
        /* get请求进行参数传递 */
        this.axios.get(url, {
          params: params
        }).then(r => {
          console.log(r);
 
          //提示成功和失败,主要演示获取响应数据的方法
          if (r.data.success) {
            //可以到element-ui官网查看用法
            this.$message({
              message: '登录成功',
              type: 'success'
            });
          }else{
            this.$message({
              message: '登录失败',
              type: 'error'
            });
          }
        }).catch(e => {
          //异常信息
        });
 
      }
    }
  }
</script>
 
<style scoped>
  .login-wrap {
    box-sizing: border-box;
    width: 100%;
    height: 100%;
    padding-top: 10%;
    background-image: url('/static/imgs/books2.jpg');
    /* background-color: #3b7cf5; */
    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;
    border: 1px solid #eaeaea;
    text-align: left;
    background-color: rgba(229, 229, 229, 0.8);
  }
 
  .title {
    margin: 0px auto 40px auto;
    text-align: center;
    color: #0b0b0b;
  }
</style>

I couldn't intercept it here originally, but then I went to the Internet to find it, and it was said that it was a problem with the order in which the mocks were introduced. I would just change the order later and it would be fine.

2. Construction of the menu on the left side of the navigation bar on the bus home page

2.1. First define the bus

new Vue({
  el: '#app',
  data(){
    return{
      Bus:new Vue()
    }
  },
  router,
  components: { App },
  template: '<App/>'
})

2.2 Custom interface components (complete code)

1. AppMain.vue interface total container

<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">Main</el-main>
		</el-container>
	</el-container>
</template>

<script>
	// 导入组件
	import TopNav from '@/components/TopNav.vue'
	import LeftNav from '@/components/LeftNav.vue'

	// 导出模块
	export default {
		components: {
      TopNav,LeftNav
    },data() {
      return {
        asideClass: "main-aside"
      }
    },
	created() {
      this.$root.Bus.$on("xxx", (v) => {
        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;
	}

	.main-aside {
		width: 240px !important;
		height: 100%;
		background-color: #334157;
		margin: 0px;
	}

	.main-header,
	.main-center {
		padding: 0px;
		border-left: 2px solid #333;
	}
</style>

2. LegtNav.vue left menu

 
<template>
	<el-menu default-active="2" class="el-menu-vertical-demo" background-color="#334157"
	 text-color="#fff" active-text-color="#ffd04b" :collapse="collapsed" >
		<!-- <el-menu default-active="2" :collapse="collapsed" collapse-transition router :default-active="$route.path" unique-opened class="el-menu-vertical-demo" background-color="#334157" text-color="#fff" active-text-color="#ffd04b"> -->
		<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">选项1</el-menu-item>
				<el-menu-item index="1-2">选项2</el-menu-item>
			</el-menu-item-group>
			<el-menu-item-group title="分组2">
				<el-menu-item index="1-3">选项3</el-menu-item>
			</el-menu-item-group>
			<el-submenu index="1-4">
				<template slot="title">选项4</template>
				<el-menu-item index="1-4-1">选项1</el-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("xxx", (v)=>{
      				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>

3. TopNav.vue top navigation bar

 
<template>
	<!-- <el-menu :default-active="activeIndex2" class="el-menu-demo" mode="horizontal" @select="handleSelect" background-color="#545c64"
	   text-color="#fff" active-text-color="#ffd04b">
		  <el-menu-item index="1">处理中心</el-menu-item>
		  <el-submenu index="2">
			  <template slot="title">我的工作台</template>
			  <el-menu-item index="2-1">选项1</el-menu-item>
			  <el-menu-item index="2-2">选项2</el-menu-item>
			  <el-menu-item index="2-3">选项3</el-menu-item>
			  <el-submenu index="2-4">
				  <template slot="title">选项4</template>
				  <el-menu-item index="2-4-1">选项1</el-menu-item>
				  <el-menu-item index="2-4-2">选项2</el-menu-item>
				  <el-menu-item index="2-4-3">选项3</el-menu-item>
			  </el-submenu>
		  </el-submenu>
   
		  <el-menu-item index="3" disabled>消息中心</el-menu-item>
		  <el-menu-item index="4"><a href="https://www.ele.me" target="_blank">订单管理</a></el-menu-item>
	  </el-menu> -->
	<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,
		  imgsq: require('@/assets/img/sq.png'),
		  imgshow: require('@/assets/img/show.png')
		}
	  },
	  methods: {
		doToggle() {
		  this.collapsed = !this.collapsed;
		  //将是否折叠的变量放入到总线中
		  this.$root.Bus.$emit("xxx", this.collapsed);
		},
		exit() {
		  this.$router.push({
			path: '/Login'
		  })
		}
	  }
	}
  </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>

2.3. Finally configure routing

import Vue from 'vue'
import Router from 'vue-router'
// import HelloWorld from '@/components/HelloWorld'
// 导入Login登录组件
import Login from '@/views/Login'
// 导入Register注册组件
// import Register from '@/views/Register'
import AppMain from '@/components/AppMain'
import LeftNav from '@/components/LeftNav'
import TopNav from '@/components/TopNav'
 
Vue.use(Router)
 
export default new Router({
  routes: [
    {
      path: '/',
      name: 'Login',
      component: Login
    },{
      path: '/AppMain',
      name: 'AppMain',
      component: AppMain,
      children:[
        {
          path: '/LeftNav',
          name: 'LeftNav',
          component: LeftNav
        },{
          path: '/TopNav',
          name: 'TopNav',
          component: TopNav
        }
      ]
    }
  ]
})

Finally, look at the running effect:

Guess you like

Origin blog.csdn.net/Ying_hao_kun/article/details/133298234