实战二:Vue后台整体布局

目录

一、整体布局页Manage.vue

二、菜单组件Aside.vue

三、头部组件Header.vue 


一、整体布局页Manage.vue

实现菜单展开和收缩、全局用户信息

<template>
  <el-container style="min-height: 100vh;">
    <el-aside :width="sideWidth + 'px'" style="box-shadow: 2px 0 6px rgb(0, 21, 41 / 35%);">
      <Aside :isCollapse="isCollapse" :logoTextShow="logoTextShow" />
    </el-aside>

    <el-container>
      <el-header style="border-bottom: 1px solid #ccc;">
        <Header :collapseBtnClass="collapseBtnClass" :collapse="collapse" :user="user" />
      </el-header>

      <el-main>
        <!-- 当前页面的子路由在当前位置显示 -->
        <router-view @refreshUser="getUser" />
      </el-main>
    </el-container>
  </el-container>
</template>
<script>
import Aside from '@/components/Aside.vue'
import Header from '@/components/Header.vue'

export default {
  data() {
    return {
      collapseBtnClass: 'el-icon-s-fold',
      isCollapse: false,
      sideWidth: 200,
      logoTextShow: true,
      user: {}
    };
  },

  components: {
    Aside,
    Header
  },
  created() {
    //从后台取最新数据
    this.getUser()

  },

  methods: {
    collapse() {
      this.isCollapse = !this.isCollapse;
      if (this.isCollapse) { //收缩
        this.sideWidth = 64;
        this.collapseBtnClass = 'el-icon-s-unfold';
        this.logoTextShow = false;
      }
      else { //展开
        this.sideWidth = 200;
        this.collapseBtnClass = 'el-icon-s-fold';
        this.logoTextShow = true;
      }
    },
    getUser() {
      let username = localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")).username : ""
      this.request.get("/user/username/" + username).then(res => {
        //重新赋值
        this.user = res.data

      })

    }
  }
}
</script>
<style>
.el-header {
  background-color: #fff;
  color: #333;
  line-height: 60px;

}

.el-aside {
  color: #333;
}
</style>

二、菜单组件Aside.vue

实现菜单默认展开,全局菜单列表

<template>
  <el-menu :default-openeds="opens" style="min-height:100% overflow-x:hidden" background-color="rgb(48,65,86)"
    text-color="#fff" active-text-color="#ffd04b" :collapse-transition="false" :collapse="isCollapse" router>
    <div style="height: 60px;line-height: 60px;text-align: center;">
      <img src="../assets/logo.png" alt="" style="width: 20px;position: relative; top: 5px;margin-right: 5px;">
      <b style="color: white;" v-show="logoTextShow">后台管理系统</b>
    </div>
    <div v-for="item in menus" :key="item.id">
      <div v-if="item.path">
        <el-menu-item :index="item.path">
          <i :class="item.icon"></i>
          <span slot="title">{{ item.name }}</span>
        </el-menu-item>
      </div>
      <div v-else>
        <el-submenu :index="item.id + ''">
          <template slot="title">
            <i :class="item.icon"></i>
            <span slot="title">{{ item.name }}</span>
          </template>
          <div v-for="subItem in item.children" :key="subItem.id">
            <el-menu-item :index="subItem.path">
              <i :class="subItem.icon"></i>
              <span slot="title">{{ subItem.name }}</span>
            </el-menu-item>
          </div>
        </el-submenu>
      </div>
    </div>
  </el-menu>
</template>
<script>
export default {
  name: "Aside",
  props: {
    isCollapse: Boolean,
    logoTextShow: Boolean
  },
  data() {
    return {
      menus: localStorage.getItem("menus") ? JSON.parse(localStorage.getItem("menus")) : [],
      opens: localStorage.getItem("menus") ? JSON.parse(localStorage.getItem("menus")).map(v => v.id + '') : []
    }
  }
}
</script>

 三、头部组件Header.vue 

面包屑导航(全局状态变量实现兄弟组件信息传递)、全局用户信息

<template >
  <div style="line-height: 60px; desplay:flex ">
    <div stype="flex: 1;">
      <span :class="collapseBtnClass" style="cursor: pointer; font-size: 18px" @click="collapse"></span>
      <el-breadcrumb separator="/" style="display: inline-block; margin-left: 10px;">
        <el-breadcrumb-item :to="'/'">首页</el-breadcrumb-item>
        <el-breadcrumb-item>{{ currentPathName }}</el-breadcrumb-item>
      </el-breadcrumb>

      <el-dropdown style="width: 150px; cursor: pointer; text-align: right; margin-right: 5px;">
        <div style="display: inline-block">
          <img :src="user.avatorUrl" alt=""
            style="width: 50px;border-radius: 50%;position: relative;top: 10px;right: 5px;" />
          <span>{{ user.nickname }}</span><i class="el-icon-arrow-down" style="margin-right: 5px;"></i>
        </div>
        <el-dropdown-menu slot="dropdown" style="width: 100px; text-align: center">
          <el-dropdown-item style="font-size: 14px; padding: 5px 0;">
            <router-link to="/person">个人信息</router-link>
          </el-dropdown-item>
          <el-dropdown-item style="font-size: 14px; padding: 5px 0;">
            <router-link to="/password">修改密码</router-link>
          </el-dropdown-item>
          <el-dropdown-item style="font-size: 14px; padding: 5px 0;">
            <span style="text-decoration: none;" @click="logout">退出</span>
          </el-dropdown-item>
        </el-dropdown-menu>
      </el-dropdown>
    </div>
  </div>
</template>
<script>
import store from '@/store'

export default {
  name: "Header",
  data() {
    return {
      // user:localStorage.getItem("user")?JSON.parse(localStorage.getItem("user")):{}
    }
  },
  props: {
    collapseBtnClass: String,
    collapse: Function,
    user: Object
  },
  computed: {
    currentPathName() {
      return store.state.currentPathName
    },
  },
  methods: {
    logout() {
      store.commit("logOut")
      this.$message.success("退出成功")
    }
  },
  watch: {
    currentPathName(newVal, oldVal) {
      console.log(newVal);

    }
  }
}
</script>

全局状态

import Vue from 'vue'
import Vuex from 'vuex'
import router, { resetRouter } from '@/router'


Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    currentPathName: ''
  },
  mutations: {
    setPath(state) {
      state.currentPathName = localStorage.getItem("currentPathName")
    },
    logOut() {
      localStorage.removeItem("user")
      localStorage.removeItem("menus")
      router.push('/login')
      //重置路由
      resetRouter()
    }
  }
})

export default store
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值