Kaynağa Gözat

添加 views/admin 后台管理模块, copy 的代码来自这里 https://blog.csdn.net/m0_63300795/article/details/126593107

reghao 7 ay önce
ebeveyn
işleme
6943f0bf12

+ 4 - 0
src/main.js

@@ -42,6 +42,10 @@ import '@/permission'
 Vue.config.productionTip = false // 阻止控制台打印生产模式下的消息
 Vue.prototype.baseURL = process.env.VUE_APP_SERVER_URL
 new Vue({
+  data: { // Bus总线
+    // 自定义的事件总线对象,用于父子组件的通信
+    Bus: new Vue()
+  },
   render: h => h(App),
   router,
   store

+ 23 - 0
src/router/admin.js

@@ -0,0 +1,23 @@
+const Admin = () => import('views/admin/Admin')
+const Dashboard = () => import('views/admin/Dashboard')
+
+export default {
+  path: '/background',
+  name: 'Admin',
+  component: Admin,
+  meta: { needAuth: true },
+  children: [
+    {
+      path: '',
+      name: 'Admin',
+      component: Dashboard,
+      meta: { needAuth: true }
+    },
+    {
+      path: '/background/file',
+      name: 'DiskFile',
+      component: Admin,
+      meta: { needAuth: true }
+    }
+  ]
+}

+ 2 - 0
src/router/index.js

@@ -11,6 +11,7 @@ import VoteRouter from './vote'
 import GeoRouter from './geo'
 import WenshuRouter from './wenshu'
 import DiskRouter from './disk'
+import AdminRouter from './admin'
 
 // 懒加载引入页面组件,es6语法
 // ********************************************************************************************************************
@@ -53,6 +54,7 @@ const routes = [
   GeoRouter,
   WenshuRouter,
   DiskRouter,
+  AdminRouter,
   {
     path: '/login',
     name: 'Login',

+ 75 - 0
src/views/admin/Admin.vue

@@ -0,0 +1,75 @@
+<template>
+  <el-container class-name="main-container">
+    <el-aside :class="asideClass">
+      <LeftAside />
+    </el-aside>
+    <el-container>
+      <el-header class-name="main-header">
+        <TopNav />
+      </el-header>
+      <el-main class-name="main-center">
+        <router-view />
+      </el-main>
+    </el-container>
+  </el-container>
+</template>
+
+<script>
+import TopNav from '@/views/admin/TopNav.vue'
+import LeftAside from '@/views/admin/LeftAside.vue'
+
+export default {
+  name: 'Main',
+  components: {
+    TopNav,
+    LeftAside
+  },
+  data() {
+    return {
+      collapsed: true
+    }
+  },
+  computed: { // 计算属性
+    asideClass() { // 如果collapsed属性为true就展开不样式 反之就展开样式
+      return this.collapsed ? 'main-aside-collapsed' : 'main-aside'
+    }
+  },
+  created() { // 钩子函数
+    this.$root.Bus.$on('Handle', value => {
+      this.collapsed = value
+    })
+  },
+  methods: {
+  }
+}
+</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>

+ 235 - 0
src/views/admin/Dashboard.vue

@@ -0,0 +1,235 @@
+<template>
+  <el-row>
+    <el-row class="movie-list">
+      <el-col :md="12" class="movie-list">
+        <el-card>
+          <div slot="header" class="clearfix">
+            <span>饼图</span>
+          </div>
+          <div id="chart2" style="height:400px;" />
+        </el-card>
+      </el-col>
+      <el-col :md="12" class="movie-list">
+        <el-card>
+          <div slot="header" class="clearfix">
+            <span>金字塔图</span>
+          </div>
+          <div id="chart3" style="height:400px;" />
+        </el-card>
+      </el-col>
+    </el-row>
+  </el-row>
+</template>
+
+<script>
+import * as echarts from 'echarts'
+
+export default {
+  name: 'Dashboard',
+  data() {
+    return {
+    }
+  },
+  mounted() {
+    this.initChart2()
+    this.initChart3()
+  },
+  created() {
+  },
+  methods: {
+    initChart2() {
+      var option = {
+        tooltip: {
+          trigger: 'item'
+        },
+        legend: {
+          top: '5%',
+          left: 'center'
+        },
+        series: [
+          {
+            name: 'Access From',
+            type: 'pie',
+            radius: ['40%', '70%'],
+            avoidLabelOverlap: false,
+            padAngle: 5,
+            itemStyle: {
+              borderRadius: 10
+            },
+            label: {
+              show: false,
+              position: 'center'
+            },
+            emphasis: {
+              label: {
+                show: true,
+                fontSize: 40,
+                fontWeight: 'bold'
+              }
+            },
+            labelLine: {
+              show: false
+            },
+            data: [
+              { value: 1048, name: 'Search Engine' },
+              { value: 735, name: 'Direct' },
+              { value: 580, name: 'Email' },
+              { value: 484, name: 'Union Ads' },
+              { value: 300, name: 'Video Ads' }
+            ]
+          }
+        ]
+      }
+
+      const myChart = this.$echarts.init(document.getElementById('chart2'))
+      myChart.setOption(option, true)
+      window.addEventListener('resize', () => {
+        if (myChart) {
+          myChart.resize()
+        }
+      })
+    },
+    initChart3() {
+      var maleData = [
+        14, 4, 10, 66,
+        54, 98, 116, 144,
+        210, 358, 484, 562,
+        706, 671, 566, 345,
+        200, 92, 24, 12,
+        0.0
+      ]
+
+      var femaleData = [
+        0, 0, 0, 15, 19,
+        29, 30, 25, 27, 34,
+        36, 48, 36, 56, 60,
+        48, 36, 12, 8, 0,
+        0.0
+      ]
+
+      var maleTotal = maleData.map(function(x) {
+        return Math.abs(x)
+      }).reduce(function(a, b) {
+        return a + b
+      })
+
+      var femaleTotal = femaleData.map(function(x) {
+        return Math.abs(x)
+      }).reduce(function(a, b) {
+        return a + b
+      })
+
+      var malePercentage = maleData.map(function(x) {
+        return -(x / maleTotal * 100)
+      })
+
+      var femalePercentage = femaleData.map(function(x) {
+        return x / femaleTotal * 100
+      })
+
+      const myChart = this.$echarts.init(document.getElementById('chart3'))
+      var option = {
+        title: {
+          text: '唐朝人口金字塔', // 设置标题文本为“唐朝人口金字塔”
+          left: 'center', // 标题水平居中
+          top: '4%', // 标题距离顶部的距离为4%
+          textStyle: {
+            color: '#333', // 标题字体颜色
+            fontSize: 24, // 标题字体大小
+            fontWeight: 'bold', // 标题字体加粗
+            fontFamily: 'KaiTi, serif' // 标题字体样式,楷体或Serif字体
+          }
+        },
+        tooltip: {
+          trigger: 'axis', // 提示框触发类型为坐标轴
+          axisPointer: {
+            type: 'shadow' // 坐标轴指示器类型为阴影
+          },
+          formatter: function(params) {
+            return params[0].name + '<br/>' +
+              params[0].seriesName + ': ' + Math.abs(maleData[params[0].dataIndex]) + ' (' + Math.abs(params[0].data).toFixed(2) + '%)' + '<br/>' +
+              params[1].seriesName + ': ' + Math.abs(femaleData[params[0].dataIndex]) + ' (' + Math.abs(params[1].data).toFixed(2) + '%)'
+            // 提示框内容格式化函数,params参数包含了鼠标悬停时的数据
+          }
+        },
+        legend: {
+          data: ['男性', '女性'], // 图例数据为“男性”和“女性”
+          align: 'left', // 图例左对齐
+          top: '6%', // 图例距离顶部的距离为6%
+          right: 2 // 图例距离右边的距离为2
+        },
+        xAxis: {
+          type: 'value',
+          axisLabel: {
+            formatter: function(value) {
+              // 自定义X轴标签的格式化函数,返回绝对值百分比
+              return Math.abs(value) + '%'
+            }
+          }
+        },
+        yAxis: {
+          type: 'category',
+          data: [
+            '0-4', '5-9', '10-14', '15-19',
+            '20-24', '25-29', '30-34', '35-39', '40-44',
+            '45-49', '50-54', '55-59', '60-64', '65-69',
+            '70-74', '75-79', '80-84', '85-89', '90-94',
+            '95-99', '100 + '
+          ]
+        },
+        series: [
+          {
+            name: '男性', // 数据系列的名称
+            type: 'bar', // 系列类型为条形图
+            stack: 'total', // 数据堆叠,同一个堆叠组的数据会堆叠显示
+            itemStyle: {
+              // 条形图的颜色渐变设置
+              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                { offset: 0, color: '#3d8e86' },
+                { offset: 0.5, color: '#5da39d' },
+                { offset: 1, color: '#88bfb8' }
+              ])
+            },
+            emphasis: {
+              focus: 'series' // 强调设置
+            },
+            data: malePercentage // 男性数据百分比
+          },
+          {
+            name: '女性', // 数据系列的名称
+            type: 'bar', // 系列类型为条形图
+            stack: 'total', // 数据堆叠
+            emphasis: {
+              focus: 'series' // 强调设置
+            },
+            itemStyle: {
+              // 条形图的颜色渐变设置
+              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                { offset: 0, color: '#d2a36c' },
+                { offset: 0.5, color: '#d5c8a0' },
+                { offset: 1, color: '#dfd6b8' }
+              ])
+            },
+            data: femalePercentage // 女性数据百分比
+          }
+        ]
+      }
+
+      myChart.setOption(option, true)
+      window.addEventListener('resize', () => {
+        if (myChart) {
+          myChart.resize()
+        }
+      })
+    }
+  }
+}
+</script>
+
+<style scoped>
+.movie-list {
+  padding-bottom: 3px;
+  padding-left: 3px;
+  padding-right: 3px;
+}
+</style>

+ 99 - 0
src/views/admin/LeftAside.vue

@@ -0,0 +1,99 @@
+<template>
+  <el-menu
+    :default-active="this.$route.path"
+    class="el-menu-vertical-demo"
+    background-color="#334157"
+    text-color="#fff"
+    active-text-color="#ffd04b"
+    :collapse="collapsed"
+    :collapse-transition="collapseTransition"
+  >
+    <div class="logobox">
+      <img class="logoimg" src="@/assets/img/icon/logo.png" alt="">
+    </div>
+    <el-menu-item index="/background">
+      <i class="el-icon-menu" />
+      <span slot="title">Dashboard</span>
+    </el-menu-item>
+    <el-submenu index="/background/2">
+      <template slot="title">
+        <i class="el-icon-location" />
+        <span>导航一</span>
+      </template>
+      <el-menu-item-group>
+        <template slot="title">分组一</template>
+        <el-menu-item index="/background/2-1">选项1</el-menu-item>
+        <el-menu-item index="/background/2-2">选项2</el-menu-item>
+      </el-menu-item-group>
+      <el-menu-item-group title="分组2">
+        <el-menu-item index="/background/2-3">选项3</el-menu-item>
+      </el-menu-item-group>
+      <el-submenu index="/background/2-4">
+        <template slot="title">选项4</template>
+        <el-menu-item index="/background/2-4-1">选项1</el-menu-item>
+      </el-submenu>
+    </el-submenu>
+    <el-menu-item index="/background/3" disabled>
+      <i class="el-icon-document" />
+      <span slot="title">导航三</span>
+    </el-menu-item>
+    <el-menu-item index="/background/4">
+      <i class="el-icon-setting" />
+      <span slot="title">导航四</span>
+    </el-menu-item>
+  </el-menu>
+</template>
+<script>
+export default {
+  name: 'LeftAside',
+  data: function() {
+    return {
+      collapsed: true,
+      collapseTransition: false
+    }
+  },
+  created: function() { // 钩子函数
+    this.$root.Bus.$on('Handle', value => {
+      this.collapsed = value
+    })
+  },
+  methods: {}
+}
+</script>
+
+<style>
+.el-menu-vertical-demo:not(.el-menu--collapse) {
+  width: 240px;
+  min-height: 800px;
+}
+
+.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>

+ 63 - 0
src/views/admin/TopNav.vue

@@ -0,0 +1,63 @@
+<template>
+  <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 index="2-3" @click="exit()">退出</el-menu-item>
+    </el-submenu>
+  </el-menu>
+</template>
+
+<script>
+export default {
+  name: 'TopNav',
+  data: function() {
+    return {
+      collapsed: true,
+      imgshow: require('@/assets/img/logo.png'),
+      imgsq: require('@/assets/img/logo.png')
+    }
+  },
+  methods: {
+    doToggle() { // 主要控制collapsed为true和false
+      this.collapsed = !this.collapsed
+      this.$root.Bus.$emit('Handle', this.collapsed)
+    },
+    exit() {
+      this.$message.info('logout system')
+    }
+  }
+}
+</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>