SPA项目之首页导航+左侧树菜单

1.mockjs的使用
1.1 安装mockjs依赖

在对应的spa项目中调出命令窗口输入 npm install mockjs -D
1.2 配置mock开发环境
为了只在开发环境使用mock,而打包到生产环境时自动不使用mock,我们可以在env中做一个配置

dev.env

module.exports = merge(prodEnv, {
  NODE_ENV: '"development"',
	MOCK: 'true'
})

prod.env

module.exports = {
NODE_ENV: '"production"',
  MOCK: 'false'
}

配置到main.js中:

注意:process.env.MOCK && require(’@/mock’)一定放在APP、css之前

import Vue from 'vue'
process.env.MOCK && require('@/mock')
import 'element-ui/lib/theme-chalk/index.css'
import App from './App'

1.3 mock的使用
紧接着上回的spa项目在src目录下新建mock目录,并且导入对应文件:

在这里插入图片描述
login-mock

// const loginInfo = {
//  code: -1,
//  message: '密码错误'
// }
//使用mockjs的模板生成随机数据
const loginInfo = {
 'code|0-1': 0,
 'msg|3-10': 'msg'
}
export default loginInfo;

这个是为了模拟随机登录是否成功的效果
code|0-1 code键名 0-1取值范围

index.js

import Mock from 'mockjs' //引入mockjs,npm已安装
import action from '@/api/action' //引入请求地址
//全局设置:设置所有ajax请求的超时时间,模拟网络传输耗时
Mock.setup({
 // timeout: 400  //延时400s请求到数据
 timeout: 200 - 400 //延时200-400s请求到数据
})
//引登陆的测试数据,并添加至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)

这里是为了模拟ajax请求和拿取数据延迟效果
注1:index.js文件的作用很显然,就是将分散的xxx-mock文件集合起来.后面再添加新的mock文件,都需要在这里引入

效果:

在这里插入图片描述
2. 首页导航+左侧菜单布局
2.1 导入必要图片资源和自定义组件

在这里插入图片描述
组件:

AppMain

<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 {
  data(){
   return {
    asideClass:'main-aside'
   }
  },
  components: {
   TopNav,LeftNav
  },
 };
</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

<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>

LeftNav

<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
   }
  }
 }
</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>

将AppMain配置到路由中去,TopNav和LeftNav不需要,因为在AppMain中已经导入整合了。
为Login组件的doSub()方法中添加一行跳转代码,完成登录跳转主页面。

this.$router.push({path:'/AppMain'});//跳转主页面

主页面展示:
在这里插入图片描述
TopNav中添加一个方法完成退出登录的功能。

methods: {
			exit() {
				this.$router.push({path:'/Login'});
			}
		}

3. 左侧树菜单的收缩
这里涉及到一个Vue总线的概念:

有时候两个组件也需要通信(非父子关系)。当然Vue2.0提供了Vuex,但在简单的场景下,可以使用一个空的Vue实例作为中央事件总线。

如何实现:
3.1 定义出一个总线 Bus
main.js

new Vue({
  el: '#app',
  data(){
   return {
    Bus:new Vue({//这就是我们定义的Bus
    })
   }
  },
  router,
  components: { App },
  template: '<App/>'
})

3.2 存值取值
将TopNav中收缩的值传递到Bus中:

定义一个方法:

doToggle(){
    this.collapsed = !this.collapsed;
    //往我们创建的Bus中存值
    this.$root.Bus.$emit('collapsed-side-click',this.collapsed);
   }

AppMain中获取Bus中存的值,并根据值改变对应样式。

created(){//钩子函数 对值重新进行渲染
   //获取Bus里存的值
   this.$root.Bus.$on('collapsed-side-click',(v)=>{
    this.asideClass=v? 'main-aside-collapsed' : 'main-aside'
   })
  }

LeftNav中获取Bus中存的值,并根据值改变对应样式。

created(){//钩子函数 对值重新进行渲染
			//获取Bus里存的值
			this.$root.Bus.$on('collapsed-side-click',(v)=>{
				this.collapsed=v;
			})
		}

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值