# new **Repository Path**: PrinceLLsy/new ## Basic Information - **Project Name**: new - **Description**: prince的仓库 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-09-16 - **Last Updated**: 2023-02-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## CMS学员管理 > 内容管理系统(content management system,CMS) - 应对现在数据可视化的趋势,越来越多企业需要在很多场景(营销数据,生产数据,用户数据)下使用,**可视化图表**来展示体现数据,让数据更加直观,数据特点更加突出。 - 项目以黑马班级管理为背景,功能包括学生信息录入,每次成绩录入;并制作可视化看板。 - 我们以班主任老师的角色注册账号,并登录系统。 - 为了方便开发,登录后点击页面顶部的“点我初始化数据”按钮,即可为该账号随机增加56名同学(8个小组,每组7人),并为每位学生模拟了3次考试成绩。 - 后续,可以在学员管理中,增删改学员信息,也可以录入或修改成绩。 ## 重要的三个地址 - **接口文档地址**:https://docs.apipost.cn/preview/ebfa24f6d27e4f89/cf3af015f5ca6674 - **接口根路径**:http://www.itcbc.com:8000 - **线上演示地址**:http://www.itcbc.com:8888/login.html ## 关键技术 ``` bootstrap axios jquery jwt echart toastr localstorage NProgress h5 es6 ``` ## 关键业务 ``` 登录 注册 退出登录 学员信息概览 学员信息crud 省市级联 成绩信息crud . ``` ## 开发流程 ### 熟悉项目 ### 框架搭建 1. 新建一个 js文件 `./assets/js/common.js` 2. 设置 axios 的基地址 3. 设置了拦截器 显示 加载中 > 在 login.html 来引入 NProgress 中文件 ```js // 设置基地址 axios.defaults.baseURL = 'http://www.itcbc.com:8000'; // 拦截器 设置 显示加载中!! // 添加请求拦截器 axios.interceptors.request.use( function (config) { // 显示加载中 NProgress.start(); // 在发送请求之前做些什么 return config; }, function (error) { // 对请求错误做些什么 return Promise.reject(error); } ); // 添加响应拦截器 axios.interceptors.response.use( function (response) { NProgress.done(); // 对响应数据做点什么 return response; }, function (error) { NProgress.done(); // 对响应错误做点什么 return Promise.reject(error); } ); ``` 1. 新建 `assets\js\login.js` 在里面来发送post请求测试以上代 ```js axios.post('/api/login', { username: 'laowan123', password: 'laowan123', }); ``` 5. 在拦截器中 错误的提示信息处理 ```js // 添加响应拦截器 axios.interceptors.response.use( function (response) { console.log(1111); // HTTP状态码 正常 !! 触发这个函数 NProgress.done(); // 对响应数据做点什么 return response; }, function (error) { // HTTP状态码 不正常 !! 触发这个函数 console.log("=============="); // console.dir(error.response.data.message); toastr.error(error.response.data.message); console.log("=============="); NProgress.done(); // 对响应错误做点什么 return Promise.reject(error); } ); ``` 6. 由于存在很多个接口都需要携带token,当没有携带token而去访问接口数据的时候,后端会返回`401状态码`,此时我们可以在拦截器中统一处理 ```js axios.interceptors.response.use( function (response) { console.log(1111); // HTTP状态码 正常 !! 触发这个函数 NProgress.done(); // 对响应数据做点什么 return response; }, function (error) { // HTTP状态码 不正常 !! 触发这个函数 console.log("=============="); console.dir(error); toastr.error(error.response.data.message); // 判断一下当前的http状态码 是不是 401 如果是 跳转回登录页面! if (error.response.status === 401) { // 未登录 window.top.location.href="./login.html" } console.log("=============="); NProgress.done(); // 对响应错误做点什么 return Promise.reject(error); } ); ``` 7. 拦截器中 自动的携带token到请求头那里 ```js axios.interceptors.request.use( function (config) { // 在发送请求之前做些什么 // 显示加载中 NProgress.start(); // 项目中 有一些接口不需要用到token 登录和注册 if (localStorage.getItem('token')) { // 在请求头中 添加一个token config.headers.Authorization = localStorage.getItem('token'); } return config; }, function (error) { // 对请求错误做些什么 return Promise.reject(error); } ); ``` 8. 以后请求私有数据不需要手动携带token ```js axios .get('/init/data') axios .get('/student/overview', { }) ``` ### 登录注册 #### 登录和注册表单的动态切换 1. 点击 *登录* 和 *注册* 进行表单的切换显示 2. 给 *登录* 和 注册 *里面的* a标签 添加一个类名 3. 获取 *登录* 和 *注册* 的盒子 以及它里面里面的a标签 4. 分布绑定点击事件来实现 *登录*和*注册*的盒子切换显示 ```js //#region 获取dom元素 const registerBox = document.querySelector('.register'); // 注册 盒子 const loginBox = document.querySelector('.login'); // 登录 盒子 const registerA = document.querySelector('.register-a'); // 注册 a 标签 const loginA = document.querySelector('.login-a'); // 登录 a 标签 //#endregion //#region 给登录和注册的a标签都绑定点击事件 registerA.addEventListener('click', function () { // 隐藏注册 显示登录 registerBox.style.display = 'none'; loginBox.style.display = 'block'; }); loginA.addEventListener('click', function () { // 隐藏登录 显示注册 loginBox.style.display = 'none'; registerBox.style.display = 'block'; }); //#endregion ``` #### 登录 1. 获取表单数据 发送axios请求完成登录 1. 关闭表单的自动显示历史记录 给 `form` 标签添加 属性 `autocomplete="off"` 2. 给表单 绑定 submit事件 3. 在该事件中 阻止默认行为 4. 通过jq的 代码 快速获取表单的数据 5. 再发送请求 完成登录 2. 判断后端返回业务码 是否等于 0 *0 表示正常!!* 3. 把登录后的 `token` 存在 本地存储中 4. 显示 **登录成功** 提示框 `toastr` 。 在 `common.js`中来设置 弹出层的样式 ```js toastr.options = { "positionClass": "toast-center-center", } // toastr.success("Are you the six fingered man?") // toastr.info("Are you the six fingered man?") // toastr.warning("Are you the six fingered man?") toastr.error("Are you the six fingered man?") ``` 5. 一会后(1.5s) 跳转到 首页 1. 建议 路径 `location.href = "./index.html"` 在js中写要跳转的页面,参照物是当前的html 不是js文件! 2. 打开页面的方式 选择 `open with live server` ### 首页 #### 引入资源 1. 引入 NProgress 2. 引入 common.js 3. 引入 index.js ```html ``` #### 退出登录 1. 给标签绑定点击事件 2. 弹出一个确认框 3. 确定退出 1. 删除本地存储中的`token` 2. 跳转回登录页面 #### 获取登录用户的信息 显示 (先跳过) 1. 查看接口文档 (后端 获取用户信息接口 后端:不好意思 还没写完,你可以先做剩下业务吧 ) #### 初始化数据 > 该功能在正常的项目中是不存在, > > 我们实现它 只是为了让项目 和线上运行的一致 锻炼代码能力! 1. 绑定点击事件 2. 查看接口文档 #### 左侧菜单点击功能 1. 打开页面的时候 默认就显示一个菜单 ```css /* 选择了标签ul 身上必须有 show class */ .nav ul.show{ display: block; } ``` ```html ``` 2. 点击 **一级标题** 控制内容 切换显示 ```js const topAList = document.querySelectorAll('.nav>li>a '); // 一级菜单 topAList.forEach((aDom) => { aDom.addEventListener('click', function () { this.nextElementSibling.classList.toggle('show'); }); }); ``` 3. 点击 **二级标题** 自身选中 右侧内容切换显示 1. **获取标签**来绑定点击事件 ```js const subAList = document.querySelectorAll('.nav ul a '); // 二级菜单 ``` 2. 先找到以前添加过选中类的 a标签, 移除掉选中效果 3. 给当前被点击的a标签 添加 选中 效果 ```js subAList.forEach((aDom) => aDom.addEventListener('click', function () { // 先找到以前添加过选中类的 a标签, 移除掉选中效果 document.querySelector('.nav ul a.active').classList.remove("active"); // 给当前被点击的a标签 添加 选中 效果 this.classList.add("active"); }) ); ``` 4.点击左侧 超链接,右侧自动切换页面 标签 iframe标签和a标签 ### 图表概览 > 登录限制处理 > > 注意要引入哪些资源 #### 引入静态资源 ```html ``` #### 数据总览 1. 找到当前页面 发送网络请求 获取数据 2. 发现响应回来的数据中,有 `身份认证失败` 让页面跳转回登录页面。 3. 显示在对应的标签中 #### 薪资 1. 需要用到三组数据 分别是 `同学姓名`、`期望薪资`、`实际薪资` 2. 带入到 折线图中 即可 #### 成绩 1. 给菜单绑定点击事件 切换显示 **成绩菜单** ```js toggleBatchBtn.addEventListener('click', function () { // show 负责 显示标签 display:block; batch.classList.toggle("show"); }) ``` 2. 点击 **成绩菜单** 获取到它对应的成绩的次数 1. 修改了样式 ```css /* 该死前辈 留坑!!! 页面暂时只有一个ul!! */ ul { list-style: none; font-size : 12px; position : absolute; right : 20px; top : -5px; background-color: #f1f1f1; /* width : 90px; */ border-radius: 3px; z-index : 1; display: none; justify-content: space-evenly; height: 40px; width: 343px; } .show{ display: flex; } .bar ul li { box-shadow: #f1f1f1 1px 1px 4px 0px; flex:1; line-height: 40px; text-align: center; } .bar ul li a { text-decoration: none; color: #6d767e; display: block; height: 100%; } ``` 2. 修改了html ```html ``` 3. 添加了点击事件 ```js batch.addEventListener("click",function (event) { const index = event.target.dataset.index; console.log(index); }) ``` 3. 把次数 发送给后端 来获取 **分组成绩** 4. 使用 **柱状图** 来 显示 分组成绩 图表 #### 来京路线 #### 籍贯 ### 成绩管理 #### 打开页面,显示成绩数据 1. 定义一个函数,发送请求获取数据 2. 对数据遍历,生成htm标签,显示在页面中 ```js //#region 获取dom元素 const tbody = document.querySelector('tbody'); //#endregion //#region 获取成绩数据 和显示成绩 function getScore() { axios.get('/score/list').then((result) => { const data = result.data.data; let html = ''; // 对象是可以遍历 for (const key in data) { html += ` ${key} ${data[key].name} ${data[key].score[0]} ${data[key].score[1]} ${data[key].score[2]} ${data[key].score[3]} ${data[key].score[4]} `; } tbody.innerHTML = html; }); } getScore(); //#endregion ``` #### 双击表格进行修改 1. 给**目标**元素先绑定好 **双击**(短时间内快速按两下鼠标)事件 ```js div.addEventListener("dblclick",function () { console.log("双击"); }) tbody.addEventListener('dblclick', function (event) { // 目标元素 要是 td标签 同时身上有类名 score const td = event.target; if (td.tagName === 'TD' && td.className === 'score') { console.log('可以被修改'); } }); ``` 2. 在对应的 `td` 中 显示 出来 `输入框` 1. 你点击谁了 就在谁的td那里 动态的生成一个 `input` 标签 2. 在生成 td 的时候,模版,也顺带生成 `input` 标签 3. 双击事件中,找到 `td` 找到它里面 的 `input` 让它显示出来 3. 用户在输入框中数据的填写,触发 输入框 失去`焦点`事件 > 失去焦点事件 普通的标签没有!! > > 失去焦点事件 给input标签添加 不能给tbody添加 4. 获取用户最新的输入,拼接成参数 发送给后端,完成数据的修改 1. 弹出提示框 2. 自己刷新数据 ### 学员管理 #### 查询数据 打开页面,发送请求 ,获取数据 ,渲染页面 #### 删除数据 > 留个大家发挥 #### 新增数据 1. 点击 **新增学员** 显示模态框 (利用了bootstrap框架) 1. 方法一 让模态框显示 ```js $("#addModal").modal("show"); ``` 2. **方法二** 让模态框显示 ```html ``` 2. 初始化 新增表单中 城市下拉列表 - **重点把握** 1. 先显示真实的**省份**信息 1. 找一下接口 发送网络请求 获取数据 渲染到对应的 下拉列表中 ```js // 显示省份 axios.get('/geo/province').then((result) => { const provinces = result.data; let html = ""; html += provinces .map((value) => ``) .join(''); addFormProvince.innerHTML = html; }); ``` 2. **省** 下拉列表 切换的时候 加载对应 **市**信息 ```js // 绑定省份下拉列表 切换事件 - 渲染 城市下拉列表 addFormProvince.addEventListener('change', function () { // 输出你选中的 省份 // console.log(addFormProvince.value); // 根据选中的省份获取城市信息 // axios.get("/geo/city", { params: { pname: addFormProvince.value } }) axios.get(`/geo/city?pname=${addFormProvince.value}`).then((result) => { const citys = result.data; let html = ""; html += citys .map((value) => ``) .join(''); addFormCity.innerHTML = html; }); }); ``` 3. **市** 下拉列表切换的时候 加载对应 **区或者县** 信息 ```js // 绑定 城市 下拉列表 渲染 区 数据 addFormCity.addEventListener('change', function () { axios .get( `/geo/county?pname=${addFormProvince.value}&cname=${addFormCity.value}` ) .then((result) => { const countys = result.data; let html = ""; html += countys .map((value) => ``) .join(''); addFormCounty.innerHTML = html; }); }); ``` 3. 重置表单 1. 原生的html的按钮 type=reset 已经帮我们重置了很多表单组件。但是对于下拉列表,需要我们手动写代码去重置 下拉列表 ```html
``` 2. 给表单绑定 重置事件 ```js addForm.addEventListener('reset', function () { // 重置下拉列表 }); ``` 3. 事件触发,重置下拉列表的代码 完成 ```js addFormCity.innerHTML = ""; addFormCounty.innerHTML = ""; ``` 4. 点击 **确认添加** 1. 触发表单的提交事件 `submit` 触发 2. 阻止默认行为(刷新页面) 3. 使用jq的方法 快速获取表单的数据 4. 根据接口文档的要求 发送 添加学员请求 5. 添加成功 1. 关闭模态框 2. 重置表单 3. 弹出提示信息 提示用户 4. 刷新页面数据 #### 编辑数据 1. 给 **修改** 按钮 绑定点击事件 *使用事件委托* 2. 弹出模态框 *两种方式显示模态框* 3. 获取被点击数据 id ,发送请求 获取 待编辑的数据 4. 将待编辑的数据 显示在 编辑表单中 (麻烦) 5. 点击 `确认修改` 按钮 6. 快速获取表单数据(id-隐藏域) 7. 拼接成参数 发送给后端 完成修改 8. 修改成功 1. 关闭模态框 2. 重置表单标签 3. 提示用户编辑成功 4. 刷新页面数据 ##### 编辑菜单中 下拉列表 籍贯 1. 打开编辑菜单的时候,看见以前选中的城市信息 (假设已经完成) 2. 鼠标点击到 下拉列表的时候(显示更多城市下拉选择),可以重新选择 1. 写一个函数负责加载 省份信息 显示到 标签中 3. 选中了省份的时候,城市出来 4. 选中了城市的时候,区出来 ## Echarts ### 学会使用echart三个关键动作 1. 连蒙带猜 2. 查看示例 很重要(根据你的需求来查找最相似的实例) 3. 配置项手册 ### Echarts-基础配置 > 需要了解的主要配置:`series` `xAxis` `yAxis` `grid` `tooltip` `title` `legend` `color` - series - 系列列表。每个系列通过 `type` 决定自己的图表类型 - 大白话:图标数据,指定什么类型的图标,可以多个图表重叠。 - xAxis:直角坐标系 grid 中的 x 轴 - yAxis:直角坐标系 grid 中的 y 轴 - grid:直角坐标系内绘图网格 - title:标题组件 - tooltip:提示框组件 - legend:图例组件 - color:调色盘颜色列表 演示代码: ```js var option = { xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] }, yAxis: { type: 'value' }, series: [{ data: [820, 932, 901, 934, 1290, 1330, 1320], type: 'line', name:'线形图' }, { data: [22, 333, 111, 222, 444, 666, 777], type: 'bar', name:'饼状图' }], grid: { show: true }, title: { text: '标题' }, tooltip: { padding: 20 }, legend: { data: ['线形图'] }, color: ['red','green'] }; ``` ### Echarts-饼图 #### 步骤分析 1. 封装好函数,为后续传入真实数据做准备 2. 初始化echarts 3. 设置配置项,空的 option 即可 4. 创建图表 5. 查找官方示例 6. 按需求,自定义配置图表 #### 第一步:echarts基本步骤 ```js function pieChart() { let myChart = echarts.init(document.querySelector('.pie')); let option = {}; myChart.setOption(option); } ``` #### 第二步:参照官方示例 (官方示例:https://echarts.apache.org/examples/zh/editor.html?c=pie-roseType-simple) - 只留下series系列数据配置,其他全部删除。 #### 第三步:自定义配置 - 增加标题,标题颜色 #6d767e - 增加鼠标移入提示。(比如:“各地学员分布 北京市 12人 占比6.8%”) - 系列数据 - 修改 name 为 '各地学员分布' - 饼图,内圈半径 10%,外圈半径 60% - 居中显示 - 面积模式 - 扇形轮廓圆角(4px) 完成后的配置项如下: ```js let option = { tooltip: { // {a} 表示series中的name // {b} 表示数据中的series.data中的name // {c} 表示每一项的值 // {d} 表示百分比 formatter: '{a}
{b} {c}人 占比{d}%' }, title: { text: '籍贯 Hometown', textStyle: { color: '#6d767e' // 标题演示 }, }, series: [ { name: '各地学员分布', type: 'pie', // pie 表示饼图 radius: ['10%', '65%'], // 内外圈的半径 center: ['50%', '50%'], // 中心点 roseType: 'area', // area表示面积模式,radius表示半径模式 itemStyle: { // 每一项的设置 borderRadius: 4, // 扇形边缘圆角设置 }, data: [ { value: 40, name: '北京' }, { value: 38, name: '山东' }, { value: 32, name: '上海' }, { value: 30, name: '江苏' }, { value: 28, name: '河北' }, { value: 26, name: '山西' }, { value: 22, name: '河南' }, { value: 18, name: '辽宁' } ] } ] }; ``` ### Echarts-折线图 #### 步骤分析 1. 封装好函数,为后续传入真实数据做准备 2. 初始化echarts 3. 设置配置项,空的option 即可 4. 创建图表 5. 查找官方示例 6. 按需求,自定义配置图表 #### 第一步:echarts基本步骤 ```js function lineChart() { let myChart = echarts.init(document.querySelector('.line')); let option = {}; myChart.setOption(option); } ``` #### 第二步:参照官方示例 (官方示例:https://echarts.apache.org/examples/zh/editor.html?c=area-simple) - tooltip -- 输入移入的提示 - title -- 标题 - xAxis -- x轴 - yAxis -- y轴 - dataZoom -- 数据缩放组件 - series -- 系列数据 以上配置项留下,其他删除 #### 第三步:自定义配置 - 将官方示例中除了option之外的其他代码删除,并自己添加X轴数据和series中的数据。 - 系列数据 - 增加一条线 - 修改 name 为 '期望薪资' 和 '实际薪资' - 线的拐点为平滑拐点 - 线条和X轴对齐位置,无特殊标记 `symbol: 'none'` - 分析数据缩放组件 `dataZoom` - 增加标题,标题颜色 #6d767e - 分析tooltip(官方示例已带)。 - 增加图例,距离顶部20px。 - 分析坐标轴留白策略 `boundaryGap` 完成后的配置项 option 如下: ```js let option = { // 图例 legend: { top: 20, }, // 鼠标移入的提示 tooltip: { trigger: 'axis', // 轴触发 position: function (pt) { // pt是一个数组,pt[0]表示横坐标位置,'10%'表示Y轴方向始终保持距离顶部10%的距离 // 所以意思是,提示框的位置会跟随鼠标左右移动,但纵向上的位置始终保持不变。 return [pt[0], '10%']; } }, // 标题 title: { text: '薪资 Salary', textStyle: { color: '#6d767e' } }, xAxis: { type: 'category', boundaryGap: false, // x轴两边的留白策略,false表示不留空白 data: ['张三', '李四', '张飞', '赵云', '狗哥', '张三', '李四', '张飞', '赵云', '狗哥', '张三', '李四', '张飞', '赵云', '狗哥', '张三', '李四', '张飞', '赵云', '狗哥'] }, yAxis: { type: 'value', // Y轴类型为value,则留白策略指的是对数据的延伸。 // 比如,图表中的数据最大值是17000,则Y轴最大数字大约是 17000 + 17000 * 50% boundaryGap: [0, '50%'], }, // 数据缩放组件 dataZoom: [ // { // type: 'inside', // 将拖动的条内置到轴里面,看不见了,但是可以拖动 // start: 0, // end: 10 // }, { type: 'slider', // 拖动条显示到轴的外面(默认就是slider类型) start: 0, // 拖动滑块起始位置(这是一个百分比) end: 15 // 拖动滑块结束位置(这是一个百分比) } ], // 数据部分 series: [ { name: '期望薪资', type: 'line', smooth: true, // 表示使用平滑曲线 symbol: 'none', // 线上拐点位置的样式,none表示没有;也可以是实心圆、空心圆、方块..... itemStyle: { // 单独控制这条线的颜色 color: '#ee6666' }, data: [8300, 9600, 15000, 17000, 12000, 8300, 9600, 15000, 17000, 12000, 8300, 9600, 15000, 17000, 12000, 8300, 9600, 15000, 17000, 12000] }, { name: '实际薪资', type: 'line', smooth: true, symbol: 'none', itemStyle: { // 单独控制这条线的颜色 color: '#5470c6' }, data: [9600, 15000, 17000, 12000, 8300, 9600, 15000, 17000, 12000, 8300, 9600, 15000, 17000, 12000, 8300, 9600, 15000, 17000, 12000, 13000] } ] }; ``` ### Echarts-柱状图 #### 步骤分析 1. 封装好函数,为后续传入真实数据做准备 2. 初始化echarts 3. 设置配置项,空的option 即可 4. 创建图表 5. 查找官方示例 6. 按需求,自定义配置图表 #### 第一步:echarts基本步骤 ```js function barChart() { let myChart = echarts.init(document.querySelector('.barChart')); let option = {} myChart.setOption(option); } ``` #### 第二步:参照官方示例 (官方示例:https://echarts.apache.org/examples/zh/editor.html?c=mix-line-bar) - tooltip 提示组件 - legend 图例 - xAxis x轴 - yAxis y轴 - series 系列数据 以上几个配置项留下,其他删除。 #### 第三步:自定义配置 - 修改X轴及series中的数据 ```js ['1组', '2组', '3组', '4组', '5组', '6组', '7组'] [83, 57, 90, 78, 66, 76, 77, 87, 69, 92, 88, 78] [2, 1, 3, 4, 2, 5, 2, 2, 4, 1, 6, 2] [3, 2, 1, 5, 1, 2, 3, 4, 5, 2, 2, 4] [3, 2, 1, 5, 1, 2, 3, 4, 5, 2, 2, 4] ``` - 多个Y轴 - 第一个y轴(**索引0**)表示平均分,范围0~100,根据数字10,将Y轴分为10份 - 第二个y轴(**索引1**)表示人数,范围0~10(根据班级情况而定),根据数字1,将y轴分为10份。 - 系列数据 - 增加至 4 组数据,并修改每组 name - 修改每个柱子的宽度为 15px - 让平均分使用第一个Y轴(`yAxisIndex: 0`),让人数使用第二个Y轴(`yAxisIndex: 1`) - 调整网格(图表的宽高) - 上下 30px,左右 7% - 分析tooltip(官方示例已带) ```js let option = { // 网格(整个图表区域设置) grid: { top: 30, bottom: 30, left: '7%', right: '7%' }, // 鼠标移入的提示 tooltip: { trigger: 'axis', // 触发方式,axis表示轴触发,item表示每一项 axisPointer: { // 坐标轴指示器配置项 // 十字准星指示器,其他选项有 line、shadow、none(这里配合x轴的设置,组成的十字准星) type: 'cross', crossStyle: { color: '#999' } } }, // 图例 legend: {}, // X轴 xAxis: [ { type: 'category', data: ['1组', '2组', '3组', '4组', '5组', '6组', '7组'], axisPointer: { // 坐标轴指示器为阴影,配合tooltip中的设置,组成十字准星 type: 'shadow' } } ], // Y轴 yAxis: [ { type: 'value', min: 0, // y轴数据最小值 max: 100, // y轴数据最大值 interval: 10, // step步长,把y轴的数据分成多少份 axisLabel: { // Y轴文字设置 formatter: '{value}分', // Y轴文字 } }, { type: 'value', min: 0, max: 10, interval: 1, axisLabel: { formatter: '{value}人' } } ], // 数据部分(4组数据) series: [ { name: '平均分', type: 'bar', data: [83, 57, 90, 78, 66, 76, 77, 87, 69, 92, 88, 78], barWidth: '15', }, { name: '低于60分人数', type: 'bar', data: [2, 1, 3, 4, 2, 5, 2, 2, 4, 1, 6, 2], barWidth: '15', yAxisIndex: 1, // Y轴索引,1表示使用第2个Y轴 }, { name: '60到80分之间', type: 'bar', yAxisIndex: 1, // Y轴索引,1表示使用第2个Y轴 barWidth: '15', data: [1, 4, 2, 4, 5, 2, 1, 3, 3, 2, 2, 4] } , { name: '高于80分人数', type: 'bar', yAxisIndex: 1, // Y轴索引,1表示使用第2个Y轴 barWidth: '15', data: [3, 2, 1, 5, 1, 2, 3, 4, 5, 2, 2, 4] } ] }; ``` ### Echarts社区 > 社区就是一些,活跃的echart使用者,交流和贡献定制好的图表的地方。 在这里可以找到一些基于echart的高度定制好的图表,相当于基于jquery开发的插件,这里是基于echarts开发的第三方的图表。 社区示例:https://www.makeapie.com/explore.html ![image-20211104205619163](Readme/image-20211104205619163.png) ### Echarts-使用社区的示例 项目中使用的社区示例地址:https://www.makeapie.com/editor.html?c=xD4a1EBnvW 重点: - 使用社区示例,必须要查看示例引入了哪些外部js文件。 实现步骤: - 第一需要下载china.js提供中国地图的js文件 - 导入后,直接使用社区提供的配置即可。 - 自行修改 - 将背景色改为 白色 - 将 视觉映射组件(`visualMap`)中的 `show` 改为 `false` - 其他自行自愿修改。 必须知道的结论: - 哪些数据和哪些数据是对应的,必须一致 - 哪些数据能多,能错 - 哪些数据不能多,不能错 ## 补充 ### 可以折叠大段代码 > 按下 **#** ![image-20220525154808360](readme.assets/image-20220525154808360.png) ### JWT `json web token` ### iframe 1. 可以实现 **页中页** 效果 2. 父子页面不共享js和css等静态资源 3. iframe标签经常和a标签相搭配。 a标签的target 属性 要等于 iframe标签的name属性 4. 现在前端项目中 很不推荐使用 `iframe` -`面试题` 5. 子页面 想要控制自己跳转 `location.href` 6. 子页面 想要控制 父页面跳转 `window.top.location.href` ## 复习建议 1. 看着老师的码云的代码提交记录 跟上功能 2. 独立完成 `注册`功能 3. 首页 菜单点击切换选中