vue2版本《后台管理模式》(下)

news2024/9/28 13:23:21

文章目录

  • 前言
  • 一、home 页
    • 以下都属于home子组件
  • 二、header 头部 组件
  • 二、Menu 页面
  • 三、Bread 面包屑
  • 四、Footer
  • 五 、分页器: Pageing![在这里插入图片描述](https://img-blog.csdnimg.cn/fbe9bb7e84a04ccda4d3fc9f4ab9c36b.png#pic_center)
  • 六、权限管理
  • 总结


前言

这章主写内容 该要的配置都有

上章链接:《后台管理(中)》点击跳转

一、home 页

路由在《后台管理(上)》,划分组件 每个组件某个功能

<template>
  <div class="home">
    <!-- 头部 -->
    <Header></Header>
    <!-- 主体部分 -->
    <el-container class="content">
      <!-- 左侧 -->
      <Menu></Menu>
      <!-- 右侧 -->
      <el-container>
        <el-main>
          <!-- 面包屑 -->
          <Bread></Bread>
          <!-- 路由视图出口 -->
          <div class="count">
            <router-view></router-view>
          </div>
        </el-main>
        <!-- 尾部 -->
        <el-footer>
          <Footer></Footer>
        </el-footer>
      </el-container>
    </el-container>
  </div>
</template>

<script>
import Header from "@/components/common/Header";
import Bread from "@/components/common/Breadcrumb";
import Menu from "@/components/common/Menu";
import Footer from "@/components/common/Footer";
export default {
  name: "Home",
  components: {
    Header,
    Bread,
    Menu,
    Footer,
  },
};
</script>

<style lang="scss" scoped>
.home {
  width: 100%;
  height: 100%;
  .content {
    position: absolute;
    width: 100%;
    top: 60px;
    bottom: 0;
    .count {
      margin: 20px 0;
    }
  }
}
</style>

以下都属于home子组件

学生列表 StudentList

<template>
  <div class="student">
    <!-- 查询 -->
    <el-form
      :inline="true"
      :model="formInline"
      class="demo-form-inline"
      size="small"
    >
      <el-form-item label="姓名">
        <el-input v-model="formInline.name" placeholder="请输入姓名"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="find">查询</el-button>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="reset">重置</el-button>
      </el-form-item>
    </el-form>
    <!-- 表格 -->
    <!-- 1: 0-9 2: 10-19 3: 20-29 slice((当前页数-1)*每页的条数,当前页数*当前的条数) -->
    <el-table :data="compDate" border style="width: 100%">
      <el-table-column prop="name" label="姓名" align="center">
      </el-table-column>
      <el-table-column prop="age" label="年龄" align="center">
      </el-table-column>
      <el-table-column prop="sex_text" label="性别" align="center">
      </el-table-column>
      <el-table-column prop="number" label="学号" align="center">
      </el-table-column>
      <el-table-column prop="class" label="班级号" align="center">
      </el-table-column>
      <el-table-column prop="state_text" label="状态" align="center">
      </el-table-column>
      <el-table-column prop="phone" label="联系方式" align="center" width="110">
      </el-table-column>
      <el-table-column prop="address" label="地址" align="center">
      </el-table-column>

      <el-table-column align="center" label="操作" width="100">
        <template slot-scope="scope">
          <el-button
            type="danger"
            size="mini"
            icon="el-icon-delete"
            @click="del(scope.row)"
          >
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页 -->
    <el-pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="currentPage"
      :page-sizes="[5, 10, 20, 30, 50]"
      :page-size="pageSize"
      layout="total, sizes, prev, pager, next, jumper"
      :total="total"
    >
    </el-pagination>
  </div>
</template>

<script>
import { student, studentDel } from "@/api/api";

export default {
  data() {
    return {
      // 表格内的总数据
      tableData: [],
      // 查询
      formInline: {
        name: "",
      },
      // 总条数
      total: 0,
      // 每页显示的数量
      pageSize: 10,
      // 当前页
      currentPage: 1,
    };
  },
  mounted() {
    this.getData();
  },
  computed: {
    compDate() {
      return (
        // 起点
        this.tableData.slice(
          (this.currentPage - 1) * this.pageSize,
          // 终点(数据截取在终点的前一个结束)
          this.currentPage * this.pageSize
        )
      );
    },
  },
  methods: {
    // 修改每页显示的数量
    handleSizeChange(val) {
      this.pageSize = val;
      // 每次修改完成后,回到当前第一页
      this.currentPage = 1;
    },
    // 修改当前页
    handleCurrentChange(val) {
      this.currentPage = val;
    },
    // 获取数据
    getData(params) {
      student(params).then((res) => {
        if (res.data.status === 200) {
          // 表格内的总数据
          this.tableData = res.data.data;
          // 总条数
          this.total = res.data.total;
          // 循环遍历
          this.tableData.forEach((item) => {
            // 因有些后台是数组,前端显示时需要改变为汉字
            // 尽量不要去修改原数据,因为后续的使用会造成影响
            item.sex === 1 ? (item.sex_text = "男") : (item.sex_text = "女");
            item.state === "1"
              ? (item.state_text = "已入学")
              : item.state === "2"
              ? (item.state_text = "未入学")
              : (item.state_text = "休学中");
          });
        }
      });
    },
    // 删除
    del(row) {
      studentDel(row.id).then((res) => {
        if (res.data.status === 200) {
          this.$message({ message: "数据删除成功", type: "success" });
          // 重新获取数据
          this.getData();
        }
      });
      console.log(row);
    },
    // 查询
    find() {
      this.getData(this.formInline);
    },
    // 重置
    reset() {
      this.formInline = {};
      this.getData(this.formInline);
    },
  },
};
</script>

<style lang="scss">
.student {
  .demo-form-inline,
  .el-form-inline,
  .el-pagination {
    text-align: left;
  }
  .el-pagination {
    margin-top: 40px;
  }
}
</style>

信息列表 InfoList

<template>
  <div class="infolist">
    <!-- 新增按钮 -->
    <el-form :inline="true" class="demo-form-inline" size="small">
      <el-form-item>
        <el-button type="primary" @click="addStudent">新增</el-button>
      </el-form-item>
    </el-form>
    <!-- 表格 -->
    <el-table :data="compDate" style="width: 100%" border>
      <el-table-column prop="name" label="姓名" align="center">
      </el-table-column>
      <el-table-column prop="sex_text" label="性别" align="center">
      </el-table-column>
      <el-table-column prop="age" label="年龄" align="center">
      </el-table-column>
      <el-table-column prop="father" label="父亲" align="center">
      </el-table-column>
      <el-table-column prop="mather" label="母亲" align="center">
      </el-table-column>
      <el-table-column prop="time" label="入校时间" align="center">
      </el-table-column>
      <el-table-column prop="phone" label="联系方式" align="center" width="120">
      </el-table-column>
      <el-table-column prop="address" label="地址"> </el-table-column>

      <el-table-column align="center" label="操作" width="120">
        <template slot-scope="scope">
          <el-button
            type="danger"
            size="small"
            icon="el-icon-edit"
            @click="edit(scope.row)"
          >
          </el-button>
          <el-button
            type="danger"
            size="small"
            icon="el-icon-delete"
            @click="del(scope.row)"
          >
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 复用的提示框 -->
    <el-dialog
      :title="state ? '添加学生信息' : '修改学生信息'"
      :visible.sync="dialogFormVisible"
      width="500px"
    >
      <el-form :model="form" ref="form">
        <el-form-item label="姓名" prop="name" :label-width="formLabelWidth">
          <el-input v-model="form.name" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="性别" prop="sex" :label-width="formLabelWidth">
          <el-radio v-model="form.sex" label="1"></el-radio>
          <el-radio v-model="form.sex" label="2"></el-radio>
        </el-form-item>
        <el-form-item label="年龄" prop="age" :label-width="formLabelWidth">
          <el-input v-model="form.age" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="父亲" prop="father" :label-width="formLabelWidth">
          <el-input v-model="form.father" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="母亲" prop="mather" :label-width="formLabelWidth">
          <el-input v-model="form.mather" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item
          label="入校时间"
          prop="time"
          :label-width="formLabelWidth"
        >
          <el-date-picker
            v-model="form.time"
            type="date"
            format="yyyy 年 MM 月 dd 日"
            placeholder="选择日期"
            value-format="yyyy-MM-dd"
          >
          </el-date-picker>
        </el-form-item>
        <el-form-item
          label="家庭地址"
          prop="address"
          :label-width="formLabelWidth"
        >
          <el-input v-model="form.address" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item
          label="联系方式"
          prop="phone"
          :label-width="formLabelWidth"
        >
          <el-input v-model="form.phone" autocomplete="off"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="closeInfo('form')">取 消</el-button>
        <el-button type="primary" @click="sure('form')">确 定</el-button>
      </div>
    </el-dialog>
    <!-- 分页 -->
    <el-pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="currentPage"
      :hide-on-single-page="true"
      :page-sizes="[5, 10, 15, 30, 50]"
      :page-size="pageSize"
      layout="total, sizes, prev, pager, next, jumper"
      :total="total"
    >
    </el-pagination>
  </div>
</template>

<script>
import { getData, changInfo, delData } from "../../utils/table";
export default {
  data() {
    return {
      // 表格内的总数据
      tableData: [],
      // 提示框显示隐藏
      dialogFormVisible: false,
      // 区分是新增还是修改
      state: true,
      // 提示框里input的宽
      formLabelWidth: "70px",
      // 对象的setter 如果没有属性,可以创建属性,再去赋值
      // getter 会直接去找该属性,如果没有该属性,报错
      // 提示框里的值
      form: {
        name: "",
        age: "",
        sex: "",
        father: "",
        mather: "",
        time: "",
        address: "",
        phone: "",
      },
      // 分页:
      // 总条数
      total: 0,
      // 一页显示几条
      pageSize: 5,
      // 当前页
      currentPage: 1,
    };
  },
  mounted() {
    getData(this, "/info");
  },
  computed: {
    compDate() {
      // slice(0,5)获取从0到5的值
      return this.tableData.slice(
        // 起点
        (this.currentPage - 1) * this.pageSize,
        // 终点
        this.currentPage * this.pageSize
      );
    },
  },

  methods: {
    // 每页的条数改变时触发
    handleSizeChange(val) {
      this.pageSize = val;
      this.currentPage = 1;
    },
    // 当前页数改变时触发
    handleCurrentChange(val) {
      this.currentPage = val;
    },
    // 新增数据
    addStudent() {
      // 对数据进行重置
      this.form = {
        name: "",
        age: "",
        sex: "1",
        father: "",
        mather: "",
        time: "",
        address: "",
        phone: "",
      };
      // 1. 弹出 提示框
      this.dialogFormVisible = true;
      this.state = true;
    },
    // 修改数据
    edit(row) {
      // 把当前修改的数据内容添加进提示框中
      this.form = { ...row };
      this.dialogFormVisible = true;
      // 切换对话框的标题
      this.state = false;
    },
    // 取消
    closeInfo(form) {
      // 重置数据
      this.$refs[form].resetFields();
      this.dialogFormVisible = false;
    },
    // 确定
    sure(form) {
      this.dialogFormVisible = false;
      // 判断正则验证是否通过
      this.$refs[form].validate((valid) => {
        if (valid) {
          // root, method, url, form, callback
          let method = "";
          this.state ? (method = "post") : (method = "put");
          changInfo(this, method, "/info", this.form, getData);
        }
      });
    },
    // 删除
    del(row) {
      delData(this, "/info", row.id, getData);
    },
  },
};
</script>

<style lang="scss">
.infolist {
  .demo-form-inline,
  .el-form-item,
  .el-pagination {
    text-align: left;
  }
  .el-pagination {
    margin-top: 40px;
  }
}
</style>

信息管理 InfoLists

在这里插入代码片<template>
  <div class="infolist">
    <!-- 新增按钮 -->
    <el-form :inline="true" class="demo-form-inline" size="small">
      <el-form-item>
        <el-button type="primary" @click="addStudent">新增</el-button>
      </el-form-item>
    </el-form>
    <!-- 表格 -->
    <el-table :data="compDate" style="width: 100%" border>
      <el-table-column prop="name" label="姓名" align="center">
      </el-table-column>
      <el-table-column prop="sex_text" label="性别" align="center">
      </el-table-column>
      <el-table-column prop="age" label="年龄" align="center">
      </el-table-column>
      <el-table-column prop="father" label="父亲" align="center">
      </el-table-column>
      <el-table-column prop="mather" label="母亲" align="center">
      </el-table-column>
      <el-table-column prop="time" label="入校时间" align="center">
      </el-table-column>
      <el-table-column prop="phone" label="联系方式" align="center" width="120">
      </el-table-column>
      <el-table-column prop="address" label="地址"> </el-table-column>

      <el-table-column align="center" label="操作" width="120">
        <template slot-scope="scope">
          <el-button
            type="danger"
            size="small"
            icon="el-icon-edit"
            @click="edit(scope.row)"
          >
          </el-button>
          <el-button
            type="danger"
            size="small"
            icon="el-icon-delete"
            @click="del(scope.row)"
          >
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 复用的提示框 -->
    <el-dialog
      :title="state ? '添加学生信息' : '修改学生信息'"
      :visible.sync="dialogFormVisible"
      width="500px"
    >
      <el-form :model="form" ref="form">
        <el-form-item label="姓名" prop="name" :label-width="formLabelWidth">
          <el-input v-model="form.name" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="性别" prop="sex" :label-width="formLabelWidth">
          <el-radio v-model="form.sex" label="1"></el-radio>
          <el-radio v-model="form.sex" label="2"></el-radio>
        </el-form-item>
        <el-form-item label="年龄" prop="age" :label-width="formLabelWidth">
          <el-input v-model="form.age" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="父亲" prop="father" :label-width="formLabelWidth">
          <el-input v-model="form.father" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="母亲" prop="mather" :label-width="formLabelWidth">
          <el-input v-model="form.mather" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item
          label="入校时间"
          prop="time"
          :label-width="formLabelWidth"
        >
          <el-date-picker
            v-model="form.time"
            type="date"
            format="yyyy 年 MM 月 dd 日"
            placeholder="选择日期"
            value-format="yyyy-MM-dd"
          >
          </el-date-picker>
        </el-form-item>
        <el-form-item
          label="家庭地址"
          prop="address"
          :label-width="formLabelWidth"
        >
          <el-input v-model="form.address" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item
          label="联系方式"
          prop="phone"
          :label-width="formLabelWidth"
        >
          <el-input v-model="form.phone" autocomplete="off"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="closeInfo('form')">取 消</el-button>
        <el-button type="primary" @click="sure('form')">确 定</el-button>
      </div>
    </el-dialog>
    <!-- 分页 -->
    <el-pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="currentPage"
      :hide-on-single-page="true"
      :page-sizes="[5, 10, 15, 30, 50]"
      :page-size="pageSize"
      layout="total, sizes, prev, pager, next, jumper"
      :total="total"
    >
    </el-pagination>
  </div>
</template>

<script>
// import { infoDel } from "@/api/api";
import { getData, changInfo, delData } from "../../utils/table";

export default {
  data() {
    return {
      // 表格内的总数据
      tableData: [],
      // 提示框显示隐藏
      dialogFormVisible: false,
      // 区分是新增还是修改
      state: true,
      // 提示框里input的宽
      formLabelWidth: "70px",
      // 对象的setter 如果没有属性,可以创建属性,再去赋值
      // getter 会直接去找该属性,如果没有该属性,报错
      // 提示框里的值
      form: {
        name: "",
        age: "",
        sex: "",
        father: "",
        mather: "",
        time: "",
        address: "",
        phone: "",
      },
      // 分页:
      // 总条数
      total: 0,
      // 一页显示几条
      pageSize: 5,
      // 当前页
      currentPage: 1,
    };
  },
  mounted() {
    // 获取数据
    getData(this, "/info");
  },
  computed: {
    compDate() {
      // slice(0,5)获取从0到5的值
      return this.tableData.slice(
        // 起点
        (this.currentPage - 1) * this.pageSize,
        // 终点
        this.currentPage * this.pageSize
      );
    },
  },

  methods: {
    // 每页的条数改变时触发
    handleSizeChange(val) {
      this.pageSize = val;
      this.currentPage = 1;
    },
    // 当前页数改变时触发
    handleCurrentChange(val) {
      this.currentPage = val;
    },
    // 新增数据
    addStudent() {
      // 对数据进行重置
      this.form = {
        name: "",
        age: "",
        sex: "1",
        father: "",
        mather: "",
        time: "",
        address: "",
        phone: "",
      };
      // 1. 弹出 提示框
      this.dialogFormVisible = true;
      this.state = true;
    },
    // 修改数据
    edit(row) {
      // 把当前修改的数据内容添加进提示框中
      this.form = { ...row };
      this.dialogFormVisible = true;
      // 切换对话框的标题
      this.state = false;
    },
    // 取消
    closeInfo(form) {
      // 重置数据
      this.$refs[form].resetFields();
      this.dialogFormVisible = false;
    },
    // 确定
    sure(form) {
      // 判断正则验证是否通过
      this.$refs[form].validate((valid) => {
        if (valid) {
          // root, method, url, form, callback
          let method = "";
          this.state ? (method = "post") : (method = "put");
          changInfo(this, method, "/info", this.form, getData);
        }
      });
    },
    // 删除
    del(row) {
      delData(this, "/info", row.id, getData);
    },
  },
};
</script>

<style lang="scss">
.infolist {
  .demo-form-inline,
  .el-form-item,
  .el-pagination {
    text-align: left;
  }
  .el-pagination {
    margin-top: 40px;
  }
}
</style>

作业列表 WorkList

<template>
  <div class="worklist">
    <el-table :data="tableData" v-loading="loading" border style="width: 100%">
      <el-table-column
        prop="id"
        label="用户ID"
        align="center"
      ></el-table-column>
      <el-table-column
        prop="userId_text"
        label="所属班级"
        align="center"
      ></el-table-column>
      <el-table-column
        prop="title"
        label="作业名称"
        align="center"
      ></el-table-column>
      <el-table-column
        prop="completed_text"
        label="完成情况"
        align="center"
      ></el-table-column>
    </el-table>
    <!-- 分页 -->
    <Page :total="total" :url="url"></Page>
  </div>
</template>

<script>
import Page from "@/components/common/Pageing";
export default {
  components: { Page },
  data() {
    return {
      // 表格内的总数据
      tableData: [],
      // 总条数
      total: 0,
      // 加载
      loading: true,
      // 地址
      url: "/works",
    };
  },
};
</script>

<style></style>

作业管理 WorkMenu

<template>
  <div class="worklist">
    <el-table :data="tableData" v-loading="loading" border style="width: 100%">
      <el-table-column
        prop="id"
        label="用户ID"
        align="center"
      ></el-table-column>
      <el-table-column
        prop="userId_text"
        label="所属班级"
        align="center"
      ></el-table-column>
      <el-table-column
        prop="title"
        label="作业名称"
        align="center"
      ></el-table-column>
      <el-table-column
        prop="completed_text"
        label="完成情况"
        align="center"
      ></el-table-column>
    </el-table>
    <!-- 分页 -->
    <Page :total="total" :url="url"></Page>
  </div>
</template>

<script>
import Page from "@/components/common/Pageing";
export default {
  components: { Page },
  data() {
    return {
      // 表格内的总数据
      tableData: [],
      // 总条数
      total: 0,
      // 加载
      loading: true,
      // 地址
      url: "/works",
    };
  },
};
</script>

<style></style>

地图系列

都是home的子组件

数据概览 DataView

<template>
  <div class="data-view">
    <el-card>
      <div id="main1"></div>
    </el-card>
    <el-card>
      <div id="main2"></div>
    </el-card>
  </div>
</template>

<script>
import { dataView } from "@/api/api";
export default {
  // echars是一棵树
  // 这个图标是简单还是复杂,取决你在这棵树上绘制的枝干有多少
  // 树就是dom容器,初始化,挂载到dom容器上,把枝干在配置进来
  // 枝干可以在示例中,具体代码里有配置,在文档中查看具体效果
  data() {
    return {};
  },
  created() {
    dataView().then((res) => {
      if (res.data.status === 200) {
        let { legend, xAxis, series } = res.data.data;
        this.draw(legend, xAxis, series);
      }
    });
  },
  mounted() {
    // 1. 初始化echatrs实例,并挂载到dom容器中
    let myChart = this.$echarts.init(document.getElementById("main1"));
    // 2. 对照着需求,来逐个编写配置项(参考文档)和接收数据
    let option = {
      // 标题
      title: {
        text: "会话量",
      },
      tooltip: {
        // 鼠标移入
        trigger: "axis",
      },
      legend: {
        data: ["销量"],
      },
      // X轴上数据
      xAxis: {
        // 类目轴
        type: "category",
        data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"],
      },
      // Y轴上数据
      yAxis: {
        type: "value",
      },

      // 显示数据
      series: [
        {
          name: "销量",

          // 类型
          type: "bar",
          // 是否显示柱条的背景色
          showBackground: true,
          itemStyle: {},
          data: [5, 20, 36, 10, 10, 20],
        },
      ],
    };
    // 3. 将配置和数据添加到实例中
    myChart.setOption(option);
  },
  methods: {
    draw(leg, x_data, series_data) {
      let myCharts2 = this.$echarts.init(document.getElementById("main2"));
      myCharts2.setOption({
        title: { text: "会话量" },
        tooltip: {
          // 鼠标移入
          trigger: "axis",
        },
        legend: {
          data: leg,
        },
        xAxis: {
          type: "category",
          data: x_data,
        },
        yAxis: {
          type: "value",
        },
        series: series_data,
      });
    },
  },
};
</script>

<style lang="scss" scoped>
.data-view {
  width: 100%;
  display: flex;
  justify-content: space-between;
  .el-card {
    width: 50%;
    #main1,
    #main2 {
      height: 500px;
    }
  }
}
</style>

二、header 头部 组件

<template>
  <div class="header">
    <el-header>
      <div class="title">通用管理系统</div>
      <div>{{ name }}</div>
    </el-header>
  </div>
</template>

<script>
import { getToken } from "@/utils/setToken.js";
export default {
  data() {
    return {
      name: "",
    };
  },
  mounted() {
    this.name = getToken("username");
  },
};
</script>

<style lang="scss" scoped>
.header {
  .el-header {
    background-color: #2578b5;
    line-height: 60px;
    color: #fff;
    display: flex;
    justify-content: space-between;
    .title {
      width: 200px;
      font-size: 24px;
    }
  }
}
</style>

二、Menu 页面

<template>
  <div class="menu">
    <el-aside width="200px">
      <!-- router:可以使用路由,以 index 作为 path 进行路由跳转 -->
      <!-- default-active:当前激活菜单的 index -->
      <!-- background-color:背景色,text-color:字体色,active-text-color:当前激活菜单的文字颜色 -->
      <el-menu
        router
        default-active="2"
        class="el-menu-vertical-demo"
        background-color="#2578b5"
        text-color="#fff"
        active-text-color="#ffd04b"
      >
        <template v-for="(item, index) in menus">
          <!-- 判断是否需要显示 -->
          <el-submenu :index="index + ''" :key="index" v-if="!item.hidden">
            <template slot="title">
              <i :class="item.iconClass"></i>
              <span>{{ item.name }}</span>
            </template>
            <el-menu-item-group
              v-for="(child, index) in item.children"
              :key="index"
            >
              <el-menu-item :index="child.path">
                <i :class="child.iconClass"></i>
                {{ child.name }}
              </el-menu-item>
            </el-menu-item-group>
          </el-submenu>
        </template>
      </el-menu>
    </el-aside>
  </div>
</template>

<script>
export default {
  data() {
    return {
      menus: [],
    };
  },
  mounted() {
    // 获取所有路由信息并添加到 menus 数组中
    this.menus = [...this.$router.options.routes];
  },
};
</script>

<style lang="scss" scoped>
.menu {
  ::-webkit-scrollbar {
    display: none;
  }
  .el-aside {
    height: 100%;
    .el-menu {
      height: 100%;
      .fa {
        margin-right: 10px;
      }
    }
    .el-submenu .el-menu-item {
      min-width: 0;
    }
  }
}
</style>

地图概览 MapView

<template>
  <div class="map-view">
    <div id="main"></div>
  </div>
</template>

<script>
import geoJson from "echarts/map/json/china";
export default {
  data() {
    return {};
  },
  mounted() {
    let myChart = this.$echarts.init(document.getElementById("main"));
    // 注册的是中国地图,必须包括geo组件或者mep图标类型的时候才可以使用
    // 地图:世界地图,中国地图,省份地图,市区地图
    this.$echarts.registerMap("china", geoJson);
    myChart.setOption({
      // 背景色
      backgroundColor: "rgb(121,145,200)",
      // 配置项(组件)
      geo: {
        map: "china",
        // 地图的长宽比例
        aspectScale: 0.75,
        // 图层
        zoom: 1.1,
        // 样式
        itemStyle: {
          // 标准
          normal: {
            // 地图区域的颜色
            areaColor: {
              type: "radial",
              x: 0.5,
              y: 0.5,
              r: 0.8,
              // 颜色的步骤
              colorStops: [
                {
                  offset: 0,
                  color: "#09132c",
                },
                {
                  offset: 1,
                  color: "#274d68",
                },
              ],
              // 延长作用域
              globalCoord: true,
            },
            // 盒子的阴影
            shadowColor: "rgb(58,115,192)",
            // 偏移
            shadowOffsetX: 10,
            shadowOffsetY: 11,
          },
        },
        region: [
          {
            name: "南海诸岛",
            itemStyle: {
              opacity: 0,
            },
          },
        ],
      },
      series: [
        // 配置地图相关的数据参数
        {
          type: "map",
          label: {
            normal: {
              // 显示文字
              show: true,
              textStyle: {
                color: "#1DE9B6",
              },
            },
            emphasis: {
              textStyle: {
                color: "rgb(183,185,14)",
              },
            },
          },
          // 图层
          zoom: 1.1,
          map: "china",
          itemStyle: {
            normal: {
              // 背景色
              backgroundColor: "rgb(147,235,248)",
              // 边框
              borderWidth: 1,
              // 区域颜色
              areaColor: {
                type: "radial",
                x: 0.5,
                y: 0.5,
                // 文档
                r: 0.8,
                colorStops: [
                  { offset: 0, color: "rgb(34,54,150)" },
                  { offset: 1, color: "rgb(89,128,142)" },
                ],
                // 全局生效
                globalCoord: true,
              },
            },
            // 高亮效果
            emphasis: {
              areaColor: "rgb(46,229,206)",
              borderWidth: 0.1,
            },
          },
        },
      ],
    });
  },
  methods: {},
};
</script>

<style lang="scss" scoped>
.map-view {
  width: 100%;
  #main {
    width: 100%;
    height: 600px;
  }
}
</style>

分数地图 ScoreMap

<template>
  <div class="score-map">
    <div id="main"></div>
  </div>
</template>

<script>
import chinaJson from "echarts/map/json/china";
export default {
  data() {
    return {};
  },
  mounted() {
    let myChart = this.$echarts.init(document.getElementById("main"));
    this.$echarts.registerMap("china", chinaJson);

    var name_title = "中国人民大学2017年各省市计划录取人数";
    var subname = "数据爬取自千栀网\n,\n上海、浙江无文理科录取人数";
    var nameColor = " rgb(55, 75, 113)";
    var name_fontFamily = "等线";
    var subname_fontSize = 15;
    var name_fontSize = 18;
    var mapName = "china";
    var data = [
      { name: "北京", value: 177 },
      { name: "天津", value: 42 },
      { name: "河北", value: 102 },
      { name: "山西", value: 81 },
      { name: "内蒙古", value: 47 },
      { name: "辽宁", value: 67 },
      { name: "吉林", value: 82 },
      { name: "黑龙江", value: 66 },
      { name: "上海", value: 24 },
      { name: "江苏", value: 92 },
      { name: "浙江", value: 114 },
      { name: "安徽", value: 109 },
      { name: "福建", value: 116 },
      { name: "江西", value: 91 },
      { name: "山东", value: 119 },
      { name: "河南", value: 137 },
      { name: "湖北", value: 116 },
      { name: "湖南", value: 114 },
      { name: "重庆", value: 91 },
      { name: "四川", value: 125 },
      { name: "贵州", value: 62 },
      { name: "云南", value: 83 },
      { name: "西藏", value: 9 },
      { name: "陕西", value: 80 },
      { name: "甘肃", value: 56 },
      { name: "青海", value: 10 },
      { name: "宁夏", value: 18 },
      { name: "新疆", value: 67 },
      { name: "广东", value: 123 },
      { name: "广西", value: 59 },
      { name: "海南", value: 14 },
    ];

    var geoCoordMap = {};
    var toolTipData = [
      {
        name: "北京",
        value: [
          { name: "文科", value: 95 },
          { name: "理科", value: 82 },
        ],
      },
      {
        name: "天津",
        value: [
          { name: "文科", value: 22 },
          { name: "理科", value: 20 },
        ],
      },
      {
        name: "河北",
        value: [
          { name: "文科", value: 60 },
          { name: "理科", value: 42 },
        ],
      },
      {
        name: "山西",
        value: [
          { name: "文科", value: 40 },
          { name: "理科", value: 41 },
        ],
      },
      {
        name: "内蒙古",
        value: [
          { name: "文科", value: 23 },
          { name: "理科", value: 24 },
        ],
      },
      {
        name: "辽宁",
        value: [
          { name: "文科", value: 39 },
          { name: "理科", value: 28 },
        ],
      },
      {
        name: "吉林",
        value: [
          { name: "文科", value: 41 },
          { name: "理科", value: 41 },
        ],
      },
      {
        name: "黑龙江",
        value: [
          { name: "文科", value: 35 },
          { name: "理科", value: 31 },
        ],
      },
      {
        name: "上海",
        value: [
          { name: "文科", value: 12 },
          { name: "理科", value: 12 },
        ],
      },
      {
        name: "江苏",
        value: [
          { name: "文科", value: 47 },
          { name: "理科", value: 45 },
        ],
      },
      {
        name: "浙江",
        value: [
          { name: "文科", value: 57 },
          { name: "理科", value: 57 },
        ],
      },
      {
        name: "安徽",
        value: [
          { name: "文科", value: 57 },
          { name: "理科", value: 52 },
        ],
      },
      {
        name: "福建",
        value: [
          { name: "文科", value: 59 },
          { name: "理科", value: 57 },
        ],
      },
      {
        name: "江西",
        value: [
          { name: "文科", value: 49 },
          { name: "理科", value: 42 },
        ],
      },
      {
        name: "山东",
        value: [
          { name: "文科", value: 67 },
          { name: "理科", value: 52 },
        ],
      },
      {
        name: "河南",
        value: [
          { name: "文科", value: 69 },
          { name: "理科", value: 68 },
        ],
      },
      {
        name: "湖北",
        value: [
          { name: "文科", value: 60 },
          { name: "理科", value: 56 },
        ],
      },
      {
        name: "湖南",
        value: [
          { name: "文科", value: 62 },
          { name: "理科", value: 52 },
        ],
      },
      {
        name: "重庆",
        value: [
          { name: "文科", value: 47 },
          { name: "理科", value: 44 },
        ],
      },
      {
        name: "四川",
        value: [
          { name: "文科", value: 65 },
          { name: "理科", value: 60 },
        ],
      },
      {
        name: "贵州",
        value: [
          { name: "文科", value: 32 },
          { name: "理科", value: 30 },
        ],
      },
      {
        name: "云南",
        value: [
          { name: "文科", value: 42 },
          { name: "理科", value: 41 },
        ],
      },
      {
        name: "西藏",
        value: [
          { name: "文科", value: 5 },
          { name: "理科", value: 4 },
        ],
      },
      {
        name: "陕西",
        value: [
          { name: "文科", value: 38 },
          { name: "理科", value: 42 },
        ],
      },
      {
        name: "甘肃",
        value: [
          { name: "文科", value: 28 },
          { name: "理科", value: 28 },
        ],
      },
      {
        name: "青海",
        value: [
          { name: "文科", value: 5 },
          { name: "理科", value: 5 },
        ],
      },
      {
        name: "宁夏",
        value: [
          { name: "文科", value: 10 },
          { name: "理科", value: 8 },
        ],
      },
      {
        name: "新疆",
        value: [
          { name: "文科", value: 36 },
          { name: "理科", value: 31 },
        ],
      },
      {
        name: "广东",
        value: [
          { name: "文科", value: 63 },
          { name: "理科", value: 60 },
        ],
      },
      {
        name: "广西",
        value: [
          { name: "文科", value: 29 },
          { name: "理科", value: 30 },
        ],
      },
      {
        name: "海南",
        value: [
          { name: "文科", value: 8 },
          { name: "理科", value: 6 },
        ],
      },
    ];

    /*获取地图数据*/
    myChart.showLoading();
    var mapFeatures = this.$echarts.getMap(mapName).geoJson.features;
    myChart.hideLoading();
    mapFeatures.forEach(function (v) {
      // 地区名称
      var name = v.properties.name;
      // 地区经纬度
      geoCoordMap[name] = v.properties.cp;
    });

    // console.log("============geoCoordMap===================")
    // console.log(geoCoordMap)
    // console.log("================data======================")
    // console.log(data);
    // console.log(toolTipData);
    var max = 480,
      min = 9; // todo
    var maxSize4Pin = 100,
      minSize4Pin = 20;

    var convertData = function (data) {
      var res = [];
      for (var i = 0; i < data.length; i++) {
        var geoCoord = geoCoordMap[data[i].name];
        if (geoCoord) {
          res.push({
            name: data[i].name,
            value: geoCoord.concat(data[i].value),
          });
        }
      }
      return res;
    };
    let option = {
      title: {
        text: name_title,
        subtext: subname,
        x: "center",
        textStyle: {
          color: nameColor,
          fontFamily: name_fontFamily,
          fontSize: name_fontSize,
        },
        subtextStyle: {
          fontSize: subname_fontSize,
          fontFamily: name_fontFamily,
        },
      },
      tooltip: {
        trigger: "item",
        formatter: function (params) {
          if (typeof params.value[2] == "undefined") {
            var toolTiphtml = "";
            for (let i = 0; i < toolTipData.length; i++) {
              if (params.name == toolTipData[i].name) {
                toolTiphtml += toolTipData[i].name + ":<br>";
                for (let j = 0; j < toolTipData[i].value.length; j++) {
                  toolTiphtml +=
                    toolTipData[i].value[j].name +
                    ":" +
                    toolTipData[i].value[j].value +
                    "<br>";
                }
              }
            }
            // console.log(toolTiphtml);
            // console.log(convertData(data))
            return toolTiphtml;
          } else {
            let toolTiphtml = "";
            for (let i = 0; i < toolTipData.length; i++) {
              if (params.name == toolTipData[i].name) {
                toolTiphtml += toolTipData[i].name + ":<br>";
                for (let j = 0; j < toolTipData[i].value.length; j++) {
                  toolTiphtml +=
                    toolTipData[i].value[j].name +
                    ":" +
                    toolTipData[i].value[j].value +
                    "<br>";
                }
              }
            }
            // console.log(toolTiphtml);
            // console.log(convertData(data))
            return toolTiphtml;
          }
        },
      },
      // legend: {
      //     orient: 'vertical',
      //     y: 'bottom',
      //     x: 'right',
      //     data: ['credit_pm2.5'],
      //     textStyle: {
      //         color: '#fff'
      //     }
      // },
      visualMap: {
        show: true,
        min: 0,
        max: 200,
        left: "left",
        top: "bottom",
        text: ["高", "低"], // 文本,默认为数值文本
        calculable: true,
        seriesIndex: [1],
        inRange: {
          // color: ['#3B5077', '#031525'] // 蓝黑
          // color: ['#ffc0cb', '#800080'] // 红紫
          // color: ['#3C3B3F', '#605C3C'] // 黑绿
          // color: ['#0f0c29', '#302b63', '#24243e'] // 黑紫黑
          // color: ['#23074d', '#cc5333'] // 紫红
          color: ["#00467F", "#A5CC82"], // 蓝绿
          // color: ['#1488CC', '#2B32B2'] // 浅蓝
          // color: ['#00467F', '#A5CC82'] // 蓝绿
          // color: ['#00467F', '#A5CC82'] // 蓝绿
          // color: ['#00467F', '#A5CC82'] // 蓝绿
          // color: ['#00467F', '#A5CC82'] // 蓝绿
        },
      },
      /*工具按钮组*/
      // toolbox: {
      //     show: true,
      //     orient: 'vertical',
      //     left: 'right',
      //     top: 'center',
      //     feature: {
      //         dataView: {
      //             readOnly: false
      //         },
      //         restore: {},
      //         saveAsImage: {}
      //     }
      // },
      geo: {
        show: true,
        map: mapName,
        label: {
          normal: {
            show: false,
          },
          emphasis: {
            show: false,
          },
        },
        roam: true,
        itemStyle: {
          normal: {
            areaColor: "#031525",
            borderColor: "#3B5077",
          },
          emphasis: {
            areaColor: "#2B91B7",
          },
        },
      },
      series: [
        {
          name: "散点",
          type: "scatter",
          coordinateSystem: "geo",
          data: convertData(data),
          symbolSize: function (val) {
            return val[2] / 10;
          },
          label: {
            normal: {
              formatter: "{b}",
              position: "right",
              show: true,
            },
            emphasis: {
              show: true,
            },
          },
          itemStyle: {
            normal: {
              color: "#05C3F9",
            },
          },
        },
        {
          type: "map",
          map: mapName,
          geoIndex: 0,
          aspectScale: 0.75, //长宽比
          showLegendSymbol: false, // 存在legend时显示
          label: {
            normal: {
              show: true,
            },
            emphasis: {
              show: false,
              textStyle: {
                color: "#fff",
              },
            },
          },
          roam: true,
          itemStyle: {
            normal: {
              areaColor: "#031525",
              borderColor: "#3B5077",
            },
            emphasis: {
              areaColor: "#2B91B7",
            },
          },
          animation: false,
          data: data,
        },
        {
          name: "点",
          type: "scatter",
          coordinateSystem: "geo",
          symbol: "pin", //气泡
          symbolSize: function (val) {
            var a = (maxSize4Pin - minSize4Pin) / (max - min);
            var b = minSize4Pin - a * min;
            b = maxSize4Pin - a * max;
            return a * val[2] + b;
          },
          label: {
            normal: {
              show: true,
              textStyle: {
                color: "#fff",
                fontSize: 9,
              },
            },
          },
          itemStyle: {
            normal: {
              color: "#F62157", //标志颜色
            },
          },
          zlevel: 6,
          data: convertData(data),
        },
        {
          name: "Top 5",
          type: "effectScatter",
          coordinateSystem: "geo",
          data: convertData(
            data
              .sort(function (a, b) {
                return b.value - a.value;
              })
              .slice(0, 5)
          ),
          symbolSize: function (val) {
            return val[2] / 10;
          },
          showEffectOn: "render",
          rippleEffect: {
            brushType: "stroke",
          },
          hoverAnimation: true,
          label: {
            normal: {
              formatter: "{b}",
              position: "right",
              show: true,
            },
          },
          itemStyle: {
            normal: {
              color: "yellow",
              shadowBlur: 10,
              shadowColor: "yellow",
            },
          },
          zlevel: 1,
        },
      ],
    };
    myChart.setOption(option);
  },
  methods: {},
};
</script>

<style lang="scss" scoped>
.score-map {
  width: 100%;
  #main {
    width: 100%;
    height: 650px;
  }
}
</style>

旅游地图 TravelMap

<template>
  <div class="map-view">
    <div id="main"></div>
  </div>
</template>
<!--
  设置一个标签,标签设置宽高,否则不显示
  引入中国地图的数据
  初始化echarts实例,并挂载到dom中
  注册中国地图,必须在geo或map中
  this.$echarts.registerMap("china", geoJson);
  编写配置项,把配置项添加到实例中(简写)
  配置项:
  背景色
  geo:图层(zoom),长宽比例,样式(itemStyle):地图区域的颜色,阴影,阴影偏移量,特点区域的样式(region):南海诸岛
  series:相关数据的各项参数,可以分为好几层,层次显示用图层(zoom)划分,
  1. 基础地图相关的数据参数:显示文字,文字颜色,图层,样式(itemStyle):地图区域的颜色,背景色,边框,高亮效果(鼠标移入时显示样式)

  请求数据(把请求到的值:points, linesData)给23的data

  2. 配置散点图的各项参数:类型(type):散点图(气泡图),使用地理坐标系,配置何时显示特效(绘制完成后显示特效),标记的大小(默认为10)
    图层:1,data(数据),涟漪特效相关配置:动画周期,缩放比例,波纹的绘制
  3. 配置线性图的各项参数:类型(type):线性图,图层:2,线特效的配置(effect):是否显示特效(show),特效动画的时间,显示方式,特效的大小,
    拖尾的效果,取值范围 0-1,值越大效果越明显,线的样式(透明度,颜色,宽,弯曲度),data(数据)

-->
<script>
import geoJson from "@/assets/data.json";
import { travel } from "@/api/api";
export default {
  data() {
    return {};
  },
  mounted() {
    travel().then((res) => {
      if (res.data.status === 200) {
        let { points, linesData } = res.data.data;
        this.draw(points, linesData);
      }
    });
  },
  methods: {
    draw(points, linesData) {
      let myChart = this.$echarts.init(document.getElementById("main"));
      // 注册的是中国地图,必须包括geo组件或者mep图标类型的时候才可以使用
      // 地图:世界地图,中国地图,省份地图,市区地图
      this.$echarts.registerMap("china", geoJson);
      myChart.setOption({
        // 背景色
        backgroundColor: "rgb(121,145,200)",
        // 配置项(组件)
        geo: {
          map: "china",
          // 地图的长宽比例
          aspectScale: 0.75,
          // 图层
          zoom: 1.1,
          // 样式
          itemStyle: {
            // 标准
            normal: {
              // 地图区域的颜色
              areaColor: {
                type: "radial",
                x: 0.5,
                y: 0.5,
                r: 0.8,
                // 颜色的步骤
                colorStops: [
                  {
                    offset: 0,
                    color: "#09132c",
                  },
                  {
                    offset: 1,
                    color: "#274d68",
                  },
                ],
                // 延长作用域
                globalCoord: true,
              },
              // 盒子的阴影
              shadowColor: "rgb(58,115,192)",
              // 偏移
              shadowOffsetX: 10,
              shadowOffsetY: 11,
            },
          },
          region: [
            {
              name: "南海诸岛",
              itemStyle: {
                opacity: 0,
              },
            },
          ],
        },
        series: [
          // 1. 配置基础地图相关的数据参数
          {
            type: "map",
            label: {
              normal: {
                // 显示文字
                show: true,
                textStyle: {
                  color: "#1DE9B6",
                },
              },
              emphasis: {
                textStyle: {
                  color: "rgb(183,185,14)",
                },
              },
            },
            // 图层
            zoom: 1.1,
            map: "china",
            itemStyle: {
              normal: {
                // 背景色
                backgroundColor: "rgb(147,235,248)",
                // 边框
                borderWidth: 1,
                // 区域颜色
                areaColor: {
                  type: "radial",
                  x: 0.5,
                  y: 0.5,
                  // 文档
                  r: 0.8,
                  colorStops: [
                    { offset: 0, color: "rgb(34,54,150)" },
                    { offset: 1, color: "rgb(89,128,142)" },
                  ],
                  // 全局生效
                  globalCoord: true,
                },
              },
              // 高亮效果
              emphasis: {
                areaColor: "rgb(46,229,206)",
                borderWidth: 0.1,
              },
            },
          },
          // 2. 配置散点图的各项参数
          {
            // 散点图(气泡图)
            type: "effectScatter",
            // 使用地理坐标系
            coordinateSystem: "geo",
            // 配置何时显示特效(绘制完成后显示特效)
            showEffectOn: "render",
            // 标记的大小(默认为10)
            symbolSize: 10,
            // 图层
            zlevel: 1,
            // 数据
            data: points,
            // 涟漪特效相关配置
            rippleEffect: {
              // 动画周期
              period: 5,
              // 缩放比例
              scale: 4,
              // 波纹的绘制
              brushType: "fill",
            },
          },
          // 3. 配置线性图的各项参数
          {
            // 线性图
            type: "lines",
            // 图层
            zlevel: 2,
            // 线特效的配置
            effect: {
              // 是否显示特效
              show: true,
              // 特效动画的时间
              period: 4,
              // 显示方式
              symbol: "arrow",
              // 特效的大小
              symbolSize: 7,
              // 拖尾的效果,取值范围 0-1,值越大效果越明显
              trailLength: 0.6,
            },
            lineStyle: {
              normal: {
                color: "#1DE986",
                width: 1,
                opacity: 0.4,
                curveness: 0.7,
              },
            },
            data: linesData,
          },
        ],
      });
    },
  },
};
</script>

<style lang="scss" scoped>
.map-view {
  width: 100%;
  height: 100%;
  #main {
    width: 100%;
    height: 650px;
  }
}
</style>

三、Bread 面包屑

<template>
  <div class="bread">
    <el-card>
      <!-- Breadcrumb 面包屑 -->
      <el-breadcrumb separator-class="el-icon-arrow-right">
        <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
        <!-- $route.matched:获取当前页面的路由信息 -->
        <el-breadcrumb-item
          v-for="(item, index) in $route.matched"
          :key="index"
        >
          <router-link :to="{ path: item.redirect }" class="redirects">
            {{ item.name }}
          </router-link>
        </el-breadcrumb-item>
      </el-breadcrumb>
    </el-card>
  </div>
</template>

<script>
export default {};
</script>

<style lang="scss" scoped>
.bread {
  .redirects {
    font-weight: 400;
  }
}
</style>

四、Footer

<template>
  <div>
    <el-card> Frontend 2022 Csaey </el-card>
  </div>
</template>

<script>
export default {};
</script>

<style></style>

五 、分页器: Pageing在这里插入图片描述

<!-- 这里整个组件是,组件化封装,面试的时候不要忘了-->
<!-- html,css,js 都用上是组件化封装,大部分都是内部,小部分外部 -->
<template>
  <div class="workMent">
    <el-pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="page"
      :page-sizes="[10, 20, 50, 100]"
      :page-size="size"
      layout="total, sizes, prev, pager, next, jumper"
      :total="total"
      :url="url"
    >
    </el-pagination>
  </div>
</template>

<script>
// 引入模块化封装
import { getTableData } from "@/utils/table";
export default {
  // 接收父组件传递过来的值
  props: {
    url: String,
    total: Number,
  },
  data() {
    return {
      // 当前页数
      page: 1,
      // 每页显示多少条
      size: 10,
    };
  },
  // 课堂任务:getTableData() 调用了三次,能不能封装起来(已完成)
  mounted() {
    // 通过接口请求数据(封装后的接口)
    this.getTableData();
  },
  methods: {
    // 每页的条数改变时触发
    handleSizeChange(val) {
      // 每页显示多少条
      this.size = val;
      // 当前页数回到第一页
      this.page = 1;
      // 通过接口请求数据(封装后的接口)
      this.getTableData();
    },
    // 当前页数改变时触发
    handleCurrentChange(val) {
      // 当前页数
      this.page = val;
      // 通过接口请求数据(封装后的接口)
      this.getTableData();
    },
    // 通过接口请求数据(封装后的接口)
    getTableData() {
      // 模块化封装
      getTableData(
        // 传递的值
        this.$parent,
        this.url,
        { page: this.page, size: this.size },
        ["userId", "completed"],
        // 课堂练习:120分
        // { userId: ["实训", "小实训", "就业"], completed: ["已完成", "未完成"] }
        // 课堂练习:150分
        ["实训", "小实训", "就业", "已完成", "未完成"]
      );
    },
  },
};
</script>

<style lang="scss">
.workMent {
  .el-pagination {
    text-align: left;
    margin-top: 20px;
  }
}
</style>

六、权限管理

user

<template>
  <div class="user">
    <el-tree :data="menus" show-checkbox :props="props" ref="tree"> </el-tree>
    <el-button @click="getCheckenNode">通过node获取</el-button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      menus: [],
      props: {
        label: "name",
        children: "children",
      },
    };
  },
  mounted() {
    // 获取路由的值,渲染标签

    // 权限管理和动态路由的思路
    // 根据不同的用户登录上来,返回对应的路由权限菜单
    // 一般情况下可以通过树形控件达成权限的精准控制,根据不同的菜单权限
    // 前端将收集到的菜单数据,发送给后端,后端保存后
    // 用户在进行登录时,就会查询到该用户所拥有的菜单数据,返回前端,在显示对应的数据

    // 动态添加路由使用 router.addRoutes(vue-router3.x版本方法,已废弃)
    // 后续使用:router.addRoute(进行动态路由添加)
    this.menus = [...this.$router.options.routes];
  },
  methods: {
    getCheckenNode() {
      console.log(this.$refs.tree.getCheckedNodes());
    },
  },
};
</script>

<style lang="scss" scoped></style>

users

<template>
  <div class="box">
    <el-input v-model="input" placeholder="请输入内容"></el-input>
    <div class="top" ref="top">
      <div
        class="boxlist"
        v-for="(item, index) in lists"
        :key="index"
        v-bind:style="{
          backgroundColor: item,
        }"
        @click="addcolor(item)"
      >
        <p>{{ item }}</p>
      </div>
    </div>
    <el-button type="primary" @click="add">刷新</el-button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      Number: "",
      lists: [],
      input: "",
    };
  },
  mounted() {
    // 进入时调用
    this.randoms();
  },
  methods: {
    randoms() {
      // 循环
      for (var i = 0; i < 24; i++) {
        // 把获取到的值赋值给 Number
        this.Number =
          "#" +
          // 下舍入(0-1随机数 乘以 255)转换为16进制
          Math.floor(Math.random() * 255).toString(16) +
          Math.floor(Math.random() * 255).toString(16) +
          Math.floor(Math.random() * 255).toString(16);
        // 追加到 lists 中
        this.lists.push(this.Number);
      }
    },
    add() {
      // 点击清空 lists
      this.lists = [];
      // 调用封装函数
      this.randoms();
    },
    addcolor(item) {
      // 颜色在 input 框中显示
      this.input = item;
      // 背景色改变
      this.$refs.top.style.backgroundColor = item;
    },
  },
};
</script>

<style lang="scss" scoped>
.box {
  background-color: rgb(196, 191, 191);
  .top {
    display: flex;
    flex-wrap: wrap;
    .boxlist {
      width: 150px;
      height: 150px;
      margin: 25px;
      p {
        width: 100%;
        height: 30px;
        background-color: #fff;
        line-height: 30px;
      }
    }
  }
}
</style>


总结

上章链接:《后台管理(上)》点击跳转
整个项目分为3篇文章 ,希望对大家写有帮助

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/349397.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL中索引详解

目录 一.介绍 二.索引分类 三.MySQL的索引 介绍 普通索引 唯一索引 注意 主键索引 组合索引 全文索引 空间索引 删除索引 四.索引的原理 概述 Hash算法 二叉树 平衡二叉树 BTREE树 MyISAM引擎使用BTree 六.索引的特点 优点 缺点 创建索引原则 一.介绍 索引是通…

[翻译]GPDB中的文件空间与表空间

GPDB中的文件空间与表空间GreenPlum是一个快速、灵活、纯软件的分析数据处理引擎&#xff0c;具有一些工具和特性可以充分利用任意个数硬件或者虚拟环境用来部署集群。这里讨论的一个特性是使用文件空间将数据加载和查询活动与底层的IO卷匹配。一旦在集群中创建了一个物理文件空…

【C++】类与对象(三) 运算符重载 赋值重载 取地址及const取地址操作符重载

前言 本章我们接替前一章继续深入理解类的默认成员函数&#xff0c;赋值重载&#xff0c;取地址重载&#xff0c;及const取地址操作符重载 但是在讲剩下的三个默认成员函数之前&#xff0c;我们要先来了解运算符重载&#xff0c;因为赋值重载&#xff0c;取地址重载&#xff0c…

10分钟学会python对接【OpenAI API篇】

今天学习 OpenAI API&#xff0c;你将能够访问 OpenAI 的强大模型&#xff0c;例如用于自然语言的 GPT-3、用于将自然语言翻译为代码的 Codex 以及用于创建和编辑原始图像的 DALL-E。 首先获取生成 API 密钥 在我们开始使用 OpenAI API 之前&#xff0c;我们需要登录我们的 Op…

Linux 定时任务调度(crontab)整理,太实用了!

crontab命令用于设置周期性被执行的指令。该命令从标准输入设备读取指令&#xff0c;并将其存放于“crontab”文件中&#xff0c;以供之后读取和执行。可以使用crontab定时处理离线任务&#xff0c;比如每天凌晨2点更新数据等&#xff0c;经常用于系统任务调度。服务启动和关闭…

AWS攻略——创建VPC

文章目录创建一个可以外网访问的VPCCIDR主路由表DestinationTarget主网络ACL入站规则出站规则子网创建EC2测试连接创建互联网网关&#xff08;IGW&#xff09;编辑路由表参考资料在 《AWS攻略——VPC初识》一文中&#xff0c;我们在AWS默认的VPC下部署了一台可以SSH访问的机器实…

WRAN翻译

基于小波的图像超分辨残差注意力网络 Wavelet-based residual attention network for image super-resolution 代码&#xff1a; https://github.com/xueshengke/WRANSR-keras 摘要&#xff1a; 图像超分辨率技术是图像处理和计算机视觉领域的一项基础技术。近年来&#xff0c…

【流辰信息技术】做好数据管理,赋能行业全速提升产业效能

在经济快速发展的当下&#xff0c;正是各行各业大展拳脚&#xff0c;全力以赴奔赴产能提升的好契机。做好企业&#xff0c;不仅要有一颗发展雄心&#xff0c;而且还要学会运用正确的技术和发展战略&#xff0c;推动企业向前进。流辰信息技术是低代码开发领域里的服务商&#xf…

自动化测试高频面试题(含答案)

Hello&#xff0c;你们的好朋友来了&#xff01;今天猜猜我给大家带来点啥干货呢&#xff1f;最近很多小伙伴出去面试的时候经常会被问到跟自动化测试相关的面试题。所以&#xff0c;今天特意给大家整理了一些经常被公司问到的自动化测试相关的面试题。停&#xff0c;咱先收藏起…

「团队管理」前端开发者如何规划并构建UCD的中长期前端开发能力与团队

文章目录 前言一、个人规划1.1 技能和知识的提升1.2 用户研究和用户体验1.3 团队协作能力1.4 项目管理和交付能力1.5 技术创新和开发效率二、构建UCD团队2.1 人才招聘和培养2.2 角色定义和分工2.3 团队文化和价值观前言 UCD(用户中心设计)是一种基于用户需求的设计方法论,将…

五千字总结一枚测试妹纸不平凡的2022

大家好&#xff0c;我是美团程序员&#xff0c;一个混过大厂&#xff0c;待过创业公司&#xff0c;爱给开发同学提Bug的测试妹纸一枚。2022年&#xff0c;是工作的第六年&#xff0c;也是具有突破性成长的一年&#xff0c;一直挺喜欢六这个数字&#xff0c;果然不负期望&#x…

C控制语句(if,switch,goto)

一.if 1.if循环语句格式 if(expression1) statement1 else if(expression2) statement2 else if(expression3) statement3 . . . else statement(n) else if 可以使用也可以不是用。 这里我们用一个例子进行讲解 2.if else 注意事项 If else if else之间只允许有一条语句&…

Shell - 随时启动 + 固定时间启动脚本

一.引言 有一个线上任务需要在每 10 min内的 5min 后执行&#xff0c;例如 5:10、15:10 ...、55: 10&#xff0c;正常情况下需要查看 Clock Time&#xff0c;待时间到达 5min 后手动启动&#xff0c;下面实现随时启动脚本&#xff0c;定时在 x5:10 点执行。 二.实现 A.固定 5…

【第0天】SQL快速入门-了解MySQL存储引擎(SQL 小虚竹)

回城传送–》《32天SQL筑基》 文章目录零、前言一、什么是数据库引擎二、MYSQL中有哪些数据库引擎2.1、MyISAM2.2、Memoey2.3、InnoDB三、MyISAM和InnoDB的区别3.1、MYSQL版本支持默认引擎不同MyISAMInnoDB3.2、数据的存储结构不同MyISAMInnoDB3.3、存储空间的消耗不同MyISAMIn…

新闻稿写作指南

当你想要传达一则新闻&#xff0c;写一份新闻稿是非常必要的。新闻稿的目的是让读者了解某个事件或信息&#xff0c;以及提供与之相关的背景信息和重要细节。以下是新闻稿的写作指南&#xff0c;帮助你写出一份清晰、简洁、有价值的新闻稿。1、选择一个有新闻价值的主题你的新闻…

MySQL参数优化之join_buffer_size

1.查看当前值 show variables like %join_buffer_size%mysql默认该设置为128 或 256 或512k&#xff0c;各个版本有所出入 2.作用范围 在mysql中表和表进行join时候&#xff0c;无论是两个表之间还是多个表之间&#xff0c;join的情况大致分为下面几种情况 join key 有索引 …

leaflet 设置一个图层或者多个图层的透明度(075)

第075个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet中如何设置一个图层或者多个图层的透明度,利用了layer的setOpacity方法。 直接复制下面的 vue+leaflet源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代码(共137行)相关API参考:专…

Windows保护机制GS:原理及SEH异常处理突破

前言 本次文章只用于技术讨论&#xff0c;学习&#xff0c;切勿用于非法用途&#xff0c;用于非法用途与本人无关&#xff01; 所有环境均为本地环境分析&#xff0c;且在本机进行学习。 GS机制并没有对SEH提供保护&#xff0c;换句话说我们可以通过攻击程序的异常处理达到绕…

【java 高并发编程之JUC】2w字带你JUC从入门到精通

点击查看脑图目录地址,实时更新 1 什么是 JUC 1.1 JUC 简介 在 Java 中&#xff0c;线程部分是一个重点&#xff0c;本篇文章说的 JUC 也是关于线程的。JUC 就是 java.util .concurrent 工具包的简称。这是一个处理线程的工具包&#xff0c;JDK 1.5 开始出现的。 1.2 进程与…

Leetcode_part1

Content [1. Two Sum](https://leetcode.com/problems/two-sum/)Solution 1Solution 2[递归: 17. 电话号码的字母组合](https://leetcode.com/problems/letter-combinations-of-a-phone-number/)Solution 1 暴力Soulution 2 回溯Solution 3 队列[18. 四数之和](https://leetcod…