[Vue] Introduction and use of Mock.js and construction of the left menu of the homepage navigation bar

Table of contents

1. Mock.js

1.1 Introduction to mockjs

1.2 mock.js installation and configuration

1.2.1 Install mock.js

1.2.2 Introduction of mock.js

1.3 Use of mock.js

1.3.1 Preparing simulation data

1.3.2 Define interception routes

1.3.3 Testing

2. Construction of the left menu of the homepage navigation bar

2.1 Custom interface components (complete code)

2.2 Configure routing

2.3 Component displays folding and display icons

2.4 Bus completes component communication

2.5 Effect display


1. Mock.js

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

Tips: I have also talked about the two command line options -S and -G before. Here is a comprehensive explanation of the differences between these three types.

  • -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: 'ture'
})
  • prod.env.js: development environment

/* 生产环境 */
'use strict'
module.exports = {
  NODE_ENV: '"production"',
  MOCK: 'false'
}
  • main.js

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

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,
  //2-3指重复2到3次
  "msg|2-3": 'msg'
}

//将当前模块导出,导出后index.js才可以导入
export default loginInfo;

Interview question: What is the difference between const, var and let in js? Write an example each 

1. Variable promotion: There is variable promotion for var, but there is no variable promotion for let and const, that is, the variable can only be used after it is declared, otherwise an error will be reported.

2. Repeated declaration: Variables defined by var can be declared multiple times. Const and let do not allow repeated declaration of variables.

3. Add attributes to the global: The global object of the browser is window, and the global object of Node is global. Variables declared with var are global variables and will be added as attributes of the global object, but let and const will not.

4. Temporary dead zone: Before a variable is declared using the let or const commands, the variable is unavailable. Syntactically, this is called a temporary dead zone. There is no temporary dead zone for variables declared using var.

5. Initial value setting: When declaring variables, var and let do not need to set initial values. Variables declared as const must have an initial value set.

6. Block-level scope: The block scope is included by { }, let and const have block-level scope, and var does not have block-level scope. Block-level scoping solves two problems in ES5:

  • Inner variables may override outer variables
  • The loop variable used for counting is leaked as a global variable

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, "post", 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>

In this way, there is no need to interact with the background, and functional testing can be performed through mock.js simulated data.

2. Construction of the left menu of the homepage navigation bar

2.1 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">首页</el-main>
    </el-container>
  </el-container>
</template>

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

  // 导出模块
  export default {
    //组件名称
    name: 'AppMain',

    data: function() {
      return {
        asideClass: 'main-aside',
      }
    },

    //将import的组件定义的Main中以便于使用
    components: {
      TopNav,
      LeftNav
    },
    created() {
      this.$root.Bus.$on('aaa', r => {
        this.asideClass = r ? '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: #e2b100;
    margin: 0px;
  }

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

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

2. LegtNav.vue left menu

<template>
  <el-menu default-active="2" class="el-menu-vertical-demo" background-color="#ffbf00" text-color="#fff"
    active-text-color="#ffd04b" :collapse="collapsed">
    <div class="logobox">
      <img class="logoimg" src="../assets/imgs/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 {
    name: 'LeftNav',

    data: function() {
      return {
        collapsed: false
      }
    },
    created() {
      this.$root.Bus.$on('aaa', r => {
        this.collapsed = r;
      });
    }
  }
</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: #ffbf00 !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 class="el-menu-demo" mode="horizontal" background-color="#ffbf00" 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 {
    name: 'TopNav',

    data: function() {
      return {
        collapsed: false,
        //require是node中遵循CommonJS规范的模块化解决方案,支持动态引入
        imgshow: require('@/assets/imgs/show.png'),
        imgsq: require('@/assets/imgs/sq.png')
      }
    },
    methods: {
      doToggle() { //收起左侧菜单事件
        this.collapsed = !this.collapsed;
        //将是否折叠的变量放入总线
        this.$root.Bus.$emit('aaa', this.collapsed);
      },
      exit() { //退出事件
        //跳转登录界面
        this.$router.push("/")
      }
    }
  }
</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.2 Configure routing

router/index.js, import the Main component before configuring routing

import AppMain from '@/components/AppMain'
import LeftNav from '@/components/LeftNav'
import TopNav from '@/components/TopNav'

 Configure LeftNav and TopNav subcomponents into the AppMain total container:

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
        }
      ]
    }
  ]
})

 

2.3 Component displays folding and display icons

TopNav.vue: 

LeftNav.vue: 

 

2.4 Bus completes component communication

If you want to complete component integration, you need to define a bus to communicate between the parent component (AppMain) and the child component;

src/mai.js:

new Vue({
  el: '#app',
  data() {
    return {
      /* 创建一个Bus总线 */
      Bus: new Vue()
    }
  },
  router,
  components: {
    App
  },
  template: '<App/>'
})

TopNav.vue: 

Put the variable whether to fold or not into the bus for easy access by other components. 

LeftNav:

 When the component is created, it subscribes to an  'aaa' event named and assigns the received data to  collapsed the property when the event is triggered.

 

 

AppMain.vue:

When the component is created  'aaa' , it subscribes to an event named and assigns the received data to  asideClassthe property (passing true or false to assign the corresponding style) when the event is triggered.

 

2.5 Effect display

Guess you like

Origin blog.csdn.net/Justw320/article/details/133273467