一.Mock
1.什么是Mock.js
前后端分离开发开发过程当中,经常会遇到以下几个尴尬的场景:
- 老大,接口文档还没输出,我的好多活干不下去啊!
- 后端小哥,接口写好了没,我要测试啊!
前后端分离之后,前端迫切需要一种机制,不再需要依赖后端接口开发,而今天的主角mockjs就可以做到这一点。
Mock.js是一个模拟数据的生成器,用来帮助前端调试开发、进行前后端的原型分离以及用来提高自动化测试效率。
众所周知Mock.js因为两个重要的特性风靡前端:
- 数据类型丰富:支持生成随机的文本、数字、布尔值、日期、邮箱、链接、图片、颜色等。
- 拦截Ajax请求:不需要修改既有代码,就可以拦截Ajax请求,返回模拟的响应数据。
更多内容,可查看Mockjs官方
2.Mock 在软件开发中一些常见的使用场景:
- 单元测试:在单元测试中,当需要隔离被测试组件和外部依赖时,可以使用 Mock 对象来替代真实的依赖对象。这样可以确保测试的稳定性和可重复性,同时可以精确控制依赖对象的行为和返回值。
- 模拟网络请求:在开发需要与外部 API 或网络服务交互的应用程序时,可以使用 Mock 对象来模拟网络请求的响应。这样可以在没有真实网络请求的情况下进行开发和测试,提高开发效率并减少对外部资源的依赖。
- 数据库测试:在进行数据库相关操作的测试时,可以使用 Mock 对象来模拟数据库连接和查询的结果。这样可以避免对真实数据库进行操作,提高测试的速度和独立性。
- 异步任务测试:当涉及异步任务、消息队列或定时器等机制时,可以使用 Mock 对象来模拟这些机制的行为。这样可以在测试中快速并可控地触发异步任务,并验证任务的正确性和执行情况。
- 接口开发:在开发接口时,可以使用 Mock 对象作为临时实现,用于模拟尚未实现的接口的行为。这样可以并行开发前后端,快速迭代和调试接口。
- 故障注入:通过使用 Mock 对象,可以模拟系统中的故障情况,如网络错误、服务不可用等。这样可以测试应用程序对于异常情况的处理能力以及容错机制的正确性。
- 性能测试:在进行性能测试时,可以使用 Mock 对象替代部分依赖,以便更好地控制测试环境和测试条件,从而更准确地评估系统的性能指标。
Mock 的应用场景很多,以上只是一些常见的示例。在实际开发中,根据具体需求和情况,可以灵活运用 Mock 技术来辅助软件开发和测试工作。
二.将mock部署到Vue项目中
1.下载mock依赖
npm i mockjs -D
2.配置环境
开发环境配置(dev.env.js )
MOCK: 'true'
生产环境配置 (prod.env.js )
MOCK: 'false'
在main.js动态加载
//开发环境下才会引入mockjs
process.env.MOCK && require('@/mock')
3.准备造假数据
引入生成模拟数据的包
4. 连接接口,用于模拟假数据生成
在login.vue中添加这样一个方法
this.$message({ message:r.data.message, type:r.data.code==0 ? 'success ' :'error' });
效果展示
三.总线
1.传统定义
总线(Bus)是计算机系统中负责数据传输、控制信号传递和电源供应等作用的一组共享的电路线路。它是计算机中重要的组成部分,用于连接计算机各个部件,包括CPU、内存、输入输出设备等,使这些部件能够互相通信和交换数据。
总线在现代计算机中被广泛使用,不同类型的总线根据其数据传输速率、传输距离、数据长度和电压等特性进行分类。常见的总线包括系统总线、扩展总线、I/O总线、PCI总线、USB总线等。
总线的作用是使得各个部件之间能够协调工作,共同完成计算机的各项任务,同时也为计算机的升级和扩展提供了方便。由于总线的重要作用和发展潜力,目前也面临着安全性、带宽和延迟等问题,需要不断进行技术升级和优化。
2.组件通信总线
组件通信总线通常分为两类:
- 系统总线(System Bus):用于连接CPU、内存和主板上其他主要组件的总线。它由地址总线、数据总线和控制总线组成,用于CPU与内存或其他外设之间的数据传输。
- 扩展总线(Expansion Bus):用于连接各种扩展设备和接口卡,例如PCI总线、USB总线、PCIe总线等。扩展总线允许计算机系统通过插槽或端口来扩展功能,如添加显卡、声卡、网络适配器等。
组件通信总线的特点包括带宽、速度、传输协议、可扩展性、电气特性等。它的设计需要考虑不同组件之间的数据传输需求,并根据系统的性能要求进行优化。
总之,组件通信总线在计算机系统中扮演着连接不同组件、实现数据传输和通信的重要角色,为计算机的各个部件协同工作提供了基础设施。
3.实例展示
1.导入组件
2.配置路由关系
import Vue from 'vue' import Router from 'vue-router' import HelloWorld from '@/components/HelloWorld' import AppMain from '@/components/AppMain' import LeftNav from '@/components/LeftNav' import TopNav from '@/components/TopNav' import Login from '@/views/Login' import Register from '@/views/Register' Vue.use(Router) export default new Router({ routes: [ { path: '/', name: 'Login', component: Login }, { path: '/Register', name: 'Register', component: Register }, { path: '/AppMain', name: 'AppMain', component: AppMain, children:[ { path: '/TopNav', name: 'TopNav', component: TopNav }, { path: '/LeftNav', name: 'LeftNav', component: LeftNav } ] } ] })
3.展示静态页面
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">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' }; } }; </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>
TopNav.Vue
<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, imgshow:require('@/assets/img/show.png'), imgsq:require('@/assets/img/sq.png') }; } } </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>
Left.vue
<template> <el-menu default-active="2" class="el-menu-vertical-demo" background-color="#334157" text-color="#fff" active-text-color="#ffd04b" :collapse="collapsed" :collapse-transition="bb"> <!-- <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 }; } } </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>
页面展示效果
4.展示动态效果
1.构建总线
// The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' //开发环境下才会引入mockjs process.env.MOCK && require('@/mock') // 新添加1 import ElementUI from 'element-ui' // 新添加2,避免后期打包样式不同,要放在import App from './App';之前 import 'element-ui/lib/theme-chalk/index.css' import App from './App' import router from './router' // 新添加3 Vue.use(ElementUI) Vue.config.productionTip = false import axios from '@/api/http' import VueAxios from 'vue-axios' Vue.use(VueAxios,axios) /* eslint-disable no-new */ new Vue({ el: '#app', router, data(){ return { Bus:new Vue() } }, components: { App }, template: '<App/>' })
2.优化的界面
AppMain.vue
export default { components:{ TopNav,LeftNav }, data(){ return{ asideClass:'main-aside' }; }, created() { this.$root.Bus.$on('aaa',v=>{ this.asideClass=v ? 'main-aside-collapsed' : 'main-aside'; }); } };
TopNav.vue
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('aaa',this.collapsed); }, exit(){ this.$router.push("/"); } } }
left.vue
export default { data(){ return{ collapsed:false }; }, created() { this.$root.Bus.$on('aaa',v=>{ this.collapsed=v; }); } }
3.最终效果图