006-云E办首页页面

一、封装请求

后端的登录接口是返回一个token,我们除了登录接口外每一次请求都要在请求头里携带这个token方 便后端校验,因此我们需要对请求进行拦截。

utils 目录下的api.js

//请求拦截器
axios.interceptors.request.use(config=>{
    //如果存在token,请求携带这个token
    if (window.sessionStorage.getItem('tokenStr')){
        config.headers['Authorization'] = window.sessionStorage.getItem('tokenStr');
    }
    return config;
},error => {
    console.log(error);
})


修改登录请求 Login.vue


submitLogin() {
                this.$refs.loginForm.validate((valid) => {
                    if (valid) {
                        this.loading = true;
                        this.postRequest('/login', this.loginForm).then(resp => {
                            this.loading = false;
                            if (resp) {
                                //存储用户token
                                const tokenStr = resp.obj.tokenHead + resp.obj.token;
                                window.sessionStorage.setItem('tokenStr', tokenStr);
                                //页面跳转
                                let path = this.$route.query.redirect;
                                this.$router.replace((path == '/' || path == undefined) ? '/home' : path);
                            }
                        })
                    } else {
                        this.$message.error('请输入所有字段!');
                        return false;
                    }
                });
            }

二、首页页面

1、获取菜单接口数据

Vuex 是一个专为 Vue.js 应用程序开发的 状态管理模式。它采用集中式存储管理应用的所有组件的状 态,并以相应的规则保证状态以一种可预测的方式发生变化。

安装Vuex
npm install vuex --save

配置Vuex
在 src 目录下创建一个名为 store 的目录并新建一个名为 index.js 文件用来配置 Vuex

state :全局state对象,用于保存所有组件的公共数据
getters :监听state值的最新状态(计算属性)
mutations :唯一可以改变state值的方法(同步执行)
actions :异步执行mutations方法

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
 
const store = new Vuex.Store({
	state: {
		routes: []
	},
	mutations: {
		initRoutes(state, data) {
			state.routes = data;
		}
	},
	actions: {},
	modules: {}
})
export default store;

修改 main.js 增加刚才配置的 store/index.js

import store from './store'

 new Vue({ 
 router, store, render: h => h(App)
}).$mount('#app')

封装菜单请求工具类

后端接口返回的数据中 component 的值为String,我们需要将其转换为前端所需的对象并且我们需要将 数据放入到路由的配置里。所以我们需要封装菜单请求工具类实现我们的需求。

utils 目录下新建 menus.js

export const initMenu = (router, store) => {
    if (store.state.routes.length > 0) {
        return;
    }

    getRequest('/system/cfg/menu').then(data => {
        if (data) {
            //格式化Router
            let fmtRoutes = formatRoutes(data);
            //添加到router
            router.addRoutes(fmtRoutes);
            //将数据存入vuex
            store.commit('initRoutes', fmtRoutes);
            //连接WebSocket
            store.dispatch('connect');
        }
    })
}
---
 path,
component,
 name,
 iconCls,
 children,

在这里插入图片描述

2、导航守卫

vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程 中:全局的, 单个路由独享的, 或者组件级的。
记住参数或查询的改变并不会触发进入/离开的导航守卫。我们可以通过观察 $route 对象来应对这些 变化,或使用 beforeRouteUpdate 的组件内守卫。

我们可以使用 router.beforeEach 注册一个全局前置守卫
当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于 等待中。

每个守卫方法接收三个参数:
to: Route: 即将要进入的目标 路由对象
from: Route: 当前导航正要离开的路由
next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。

main.js

import {initMenu} from "./utils/menu";
router.beforeEach((to, from, next)=>{ 
if (to.path=='/'){
	 next()
} else {
initMenu(router,store); next();
} })

Home.vue

<el-aside width="200px">
    <el-menu router unique-opened>
        <el-submenu :index="index+''"
                    v-for="(item,index) in routes" :key="index"
                    v-if="!item.hidden">
            <template slot="title">
                <i :class="item.iconCls" style="color: #1accff;margin-right: 5px"></i>
                <span>{{item.name}}</span>
            </template>
            <el-menu-item :index="children.path"
                          v-for="(children,indexj) in item.children" :key="indexj">
                {{children.name}}
            </el-menu-item>
        </el-submenu>
    </el-menu>
</el-aside>

在这里插入图片描述

测试
在这里插入图片描述

3、菜单图标

我们使用了Font Awesome的图标做为菜单图标,使用前先安装Font Awesome
npm install font-awesome
导入Font Awesome (main.js)

import 'font-awesome/css/font-awesome.min.css'
<i style="color: #1accff;margin-right: 5px" :class="item.iconCls"></i>

在这里插入图片描述

三、标题

在这里插入图片描述

1、获取用户信息

之前登录时只是获取用户token,并没有获取用户信息进行展示。我们可以在全局前置守卫时获取用户 信息并存储在SessionStorage 中方便使用

router.beforeEach((to, from, next) => {
    if (window.sessionStorage.getItem('tokenStr')) {
        initMenu(router, store);
        if (!window.sessionStorage.getItem('user')) {
            //判断用户信息是否存在
            return getRequest('/admin/info').then(resp => {
                if (resp) {
                    //存入用户信息
                    window.sessionStorage.setItem('user', JSON.stringify(resp));
                    store.commit('INIT_ADMIN', resp);
                    next();
                }
            })             
        }
        next(); 
		//如果没有登录想进入某个页面,则调到登录界面
    } else {
        if (to.path == '/') {
            next();
        } else {
            next('/?redirect=' + to.path);
			// /? 问号才是传参。
        }
    }
}) 

在首页展示:用ElemenUI

<el-dropdown class="userInfo" @command="commandHandler">
   <span class="el-dropdown-link">
     {{user.name}}<i><img :src="user.userFace"></i>
   </span>
     <el-dropdown-menu slot="dropdown">
         <el-dropdown-item command="userinfo">个人中心</el-dropdown-item>
         <el-dropdown-item command="setting">设置</el-dropdown-item>
         <el-dropdown-item command="logout">注销登录</el-dropdown-item>
     </el-dropdown-menu> 	 	
 </el-dropdown>
-------------------------------------

---------------------------------
<script>
	export default {
		name: 'Home',
		data(){
			return{
				user: JSON.parse(window.sessionStorage.getItem('user'))
			}
		},
		computed: {
			routes() {
				return this.$store.state.routes;
			}
		},
		methods: {
		        goChat() {
		            this.$router.push('/chat');
		        },
		        commandHandler(command) {
		            if (command == 'logout') {
		                this.$confirm('此操作将注销登录, 是否继续?', '提示', {
		                    confirmButtonText: '确定',
		                    cancelButtonText: '取消',
		                    type: 'warning'
		                }).then(() => {
		                    //注销登录
		                    this.postRequest('/logout');
		                    //清空用户信息
		                    window.sessionStorage.removeItem('tokenStr');
		                    window.sessionStorage.removeItem('user');
		                    //清空菜单
		                    this.$store.commit('initRoutes', []);
		                    //跳转到登录页
		                    this.$router.replace('/')
		                }).catch(() => {
		                    this.$message({
		                        type: 'info',
		                        message: '已取消操作'
		                    });
		                });
		            }
		            if (command == 'userinfo') {
		                this.$router.push('/userinfo');
		            }
		        }
		    }
		}

2、面包屑效果

在这里插入图片描述

home.vue

<el-main>
   <el-breadcrumb separator-class="el-icon-arrow-right"
                  v-if="this.$router.currentRoute.path!='/home'">
       <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
       <el-breadcrumb-item>{{this.$router.currentRoute.name}}</el-breadcrumb-item>
   </el-breadcrumb>
   <div class="homeWelcome" v-if="this.$router.currentRoute.path=='/home'">
       欢迎来到云E办系统!
   </div>
   <router-view class="homeRouterView"/>
</el-main>
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值