let 变量 = echarts.init(盒子)
let 配置项 = {}
变量.setOption(配置项)
<body>
<!-- 准备一个具有宽高的盒子 -->
<div style="width: 600px; height: 400px;"></div>
<!-- 引入echarts -->
<script src="./lib/echarts.min.js"></script>
<script>
// 1. 初始化echarts(写法固定)
// let 变量 = echarts.init(盒子)
let myChart = echarts.init(document.querySelector('div'))
// 2. 配置echarts图表(配置项决定了图表的样子)
// let 配置项 = {}
let option = {
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
data: [150, 230, 224, 218, 135, 147, 260],
type: 'line'
}
]
}
// 3. 根据配置项,创建图表(写法固定)
myChart.setOption(option) // setOption 第1个O是大写的
</script>
</body>
title - 标题
xAxis - X轴配置
yAxis - Y轴配置
series - 系列数据
color - 颜色配置
grid - 坐标轴区域的配置,比如配置距离顶部 100 像素
legend - 图例配置
tooltip - 鼠标移入提示
let option = {
// 标题配置
title: {
text: '我的第1个图表', // 主标题文本
left: 'center', // 主标题的位置
textStyle: {
color: 'red',
// 要求 标题的字体大小是 24px
fontSize: 24
},
},
// X轴配置
xAxis: {
type: 'category',
data: ['星期一', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
axisLabel: {
color: 'blue' // 坐标轴文字的颜色
}
},
// Y轴配置
yAxis: {
type: 'value'
},
// 下面是构成图表的必须的配置,叫做系列数据
series: [
// 数组中的每一个小对象,就是一个图形
{
// data 构成图表的数据
data: [150, 230, 224, 218, 135, 147, 260],
// type 表示图表的类型:(line-折线)(bar-柱状图)(pie-饼图)(map-地图)
type: 'line',
name: '订单量'
},
{
data: [250, 130, 124, 118, 235, 247, 160],
type: 'line',
name: '销售额'
},
{
data: [50, 30, 24, 18, 35, 47, 60],
type: 'bar',
barWidth: '60%', // 控制柱子的宽度
name: '纯收入'
}
],
// 颜色配置
color: ['red', 'green', {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0, color: 'red' // 0% 处的颜色
}, {
offset: 1, color: 'blue' // 100% 处的颜色
}],
global: false // 缺省为 false
}],
// 网格配置(坐标轴这个区域)
grid: {
top: 100 // 调整坐标轴区域的位置
},
// 图例(用于表达 每个图形的意义)
// 需要series中,每项数据必须定义name名字
legend: {
top: 60
},
// 提示框组件
tooltip: {
// 提示的触发方式
// 默认是 item,鼠标放到每一项上才能提示
// 可选 axis ,鼠标放到轴上即可提示
trigger: 'axis',
}
}
// ------------------- 折线图 --------------------------------
function lineChart () {
let myChart = echarts.init(document.querySelector('#line'))
let option = {}
myChart.setOption(option) // 第1个O是大写的
}
lineChart()
官方示例代码如下:
let 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',
smooth: true
}
]
}
增加标题(title)
X 轴(xAxis)
Y 轴(yAxis)
鼠标移入提示(tooltip)
网格(grid)
颜色(color)
系列数据(series)
function classSalaryChart () {
let myChart = echarts.init(document.querySelector('#salary'))
let option = {}
myChart.setOption(option) // 第1个O是大写的
}
classSalaryChart()
增加标题(title)
系列数据(series)
[
{ value: 1048, name: '1万以下' },
{ value: 235, name: '1万-2万' },
{ value: 580, name: '1.5万-2万' },
{ value: 484, name: '2万以上' }
]
图例(legend)
鼠标移入提示(tooltip)(不需要改)
颜色(color)
function sexSalaryChart () {
let myChart = echarts.init(document.querySelector('#gender'))
let option = {}
myChart.setOption(option)
}
sexSalaryChart()
复制之后
标题设置:
{}
表示[{标题1}, {标题2}, {标题3}]
表示title: [
{
text: '男女生薪资分布',
top: 15,
left: 10,
textStyle: {
fontSize: 16
}
},
{
text: '男生',
top: '50%',
left: '45%',
textStyle: {
fontSize: 12
}
},
{
text: '女生',
top: '85%',
left: '45%',
textStyle: {
fontSize: 12
}
}
],
要做地图,除了引入 echarts.min.js 之外,还需要地区的配置文件。
比如做中国地图,需要引入 china.js 才可以。
更多地图做法,参考群里的 7 分钟视频。
// ------------------- 地图 ----------------------------------
function mapChart () {
let myChart = echarts.init(document.querySelector('#map'))
let option = {
// 从 0 开始,自己写配置
}
myChart.setOption(option)
}
mapChart()
标题(title)
系列数据(series)
// 因为用地图表示每个省有几名同学
// 所以可以提前准备好数据
const mapData = [
{ name: '南海诸岛', value: 0 },
{ name: '北京', value: 3 },
{ name: '天津', value: 2 },
{ name: '上海', value: 4 },
{ name: '重庆', value: 1 },
{ name: '河北', value: 20 },
{ name: '河南', value: 23 },
{ name: '云南', value: 0 },
{ name: '辽宁', value: 15 },
{ name: '黑龙江', value: 12 },
{ name: '湖南', value: 2 },
{ name: '安徽', value: 5 },
{ name: '山东', value: 18 },
{ name: '新疆', value: 0 },
{ name: '江苏', value: 5 },
{ name: '浙江', value: 1 },
{ name: '江西', value: 4 },
{ name: '湖北', value: 3 },
{ name: '广西', value: 2 },
{ name: '甘肃', value: 9 },
{ name: '山西', value: 11 },
{ name: '内蒙古', value: 14 },
{ name: '陕西', value: 14 },
{ name: '吉林', value: 10 },
{ name: '福建', value: 0 },
{ name: '贵州', value: 0 },
{ name: '广东', value: 0 },
{ name: '青海', value: 3 },
{ name: '西藏', value: 0 },
{ name: '四川', value: 1 },
{ name: '宁夏', value: 1 },
{ name: '海南', value: 0 },
{ name: '台湾', value: 0 },
{ name: '香港', value: 0 },
{ name: '澳门', value: 0 }
]
然后series中,通过 data 指定使用这些数据
series: [
{
type: 'map',
...
... 其他配置略
data: mapData // 指定数据
}
]
鼠标移入提示(tooltip)
河北:20 位学员
这样的格式视觉映射组件(visualMap)
网格(grid)
X 轴(xAxis)
Y 轴(yAxis)
鼠标移入提示(tooltip)
系列数据(series)
series: [
{
data: [12200, 17932, 13901, 13934, 21290, 23300, 13300, 13320],
type: 'bar',
name: '期望薪资' // 这个数据的名字,可以在鼠标移入的提示上显示
},
{
data: [22820, 19932, 16901, 15934, 31290, 13300, 14300, 18320],
type: 'bar',
name: '就业薪资' // 这个数据的名字,可以在鼠标移入的提示上显示
}
]
颜色(color)
作业:自己做一个自己家乡的地图(做市级地图,参考群里的视频)
作用一:获取表单各项的值,语法: let data = val(表单)
作用二:修改的时候,可以做数据回填,语法: val(表单, 数据)
// 注册业务:获取输入框的账号、密码,提交给接口即可;
// 如果有问题,则提示一下(比如账号已存在、比如账号太长了、.......)
// 如果注册成功,则跳转到登录页去登录
document.querySelector('#btn-login').addEventListener('click', function (e) {
e.preventDefault()
// 使用插件收集表单各项的值
// let data = val(表单) // val() 函数就会把表单各项的值收集到(要求表单各项必须有name属性)
let data = val(document.querySelector('form')) // serialize(表单, { hash: true })
// console.log(data) // {username: 'aaa', password: 'bbb'}
// 简单的验证一下数据格式
if (data.username.length < 2 || data.username.length > 30) {
message.error('用户名长度应该是2~30位')
return
}
if (data.password.length < 6 || data.password.length > 30) {
message.error('密码长度应该是6~30位')
return
}
// Ajax把数据提交给接口
axios({
method: 'POST',
url: 'http://ajax-api.itheima.net/register',
data: data
}).then(result => {
// 成功后提示
message.success(result.data.message) // 提示注册成功
// 清空输入框的值
document.querySelector('form').reset() // 重置表单
// 跳转到登录页
setTimeout(() => {
// 等一下,等提示隐藏了再跳转
location.href = './login.html'
}, 1500)
}).catch(err => {
// console.dir(err)
message.error(err.response.data.message) // 提示账号已存在
})
})
因为登录的业务逻辑和注册差不多。
所以,复制上述注册的代码 到 login.html 中。
并修改以下内容:
http://ajax-api.itheima.net/login
location.href = './index.html'
具体到代码:
localStorage.setItem('token', result.data.data.token)
// ====================================================================================
// 发送请求,获取接口数据,把数据渲染到页面中,把数据用到图表中
axios({
url: 'http://ajax-api.itheima.net/dashboard',
headers: {
Authorization: localStorage.getItem('token')
}
}).then(result => {
console.log(result)
})
axios配置好请求根路径之后,后续所有的请求,都不用写请求根路径了。
配置语法:axios.defaults.baseURL = 'http://ajax-api.itheima.net'
只要有上述这行代码,后面所有的请求,都不用加 请求根路径了。
项目中,由于每个html文件,都引入了 common.js 的文件,所以,我们可以选择把 统一的配置,放到 common.js 中。
同理,也可以全局统一配置请求头,代码如下。
common.js 中的代码:
// 上面这个代码处理过度动画(默认加上不用管)
document.addEventListener('DOMContentLoaded', () => {
setTimeout(() => {
document.body.classList.add('sidenav-pinned')
document.body.classList.add('ready')
}, 200)
})
// 加入axios的配置
// 配置请求根路径
axios.defaults.baseURL = 'http://ajax-api.itheima.net'
// 配置请求头
axios.defaults.headers.common['Authorization'] = localStorage.getItem('token')
拦截器分为
参考地址:https://www.axios-http.cn/docs/interceptors
项目中,如果是token 的问题(不是忘记携带了,就是token过期了),接口都会响应 401 状态码。
所以,添加响应拦截器,判断响应状态码是否是401,如果是,则跳转到登录。
在common.js中,添加如下代码:
// 添加响应拦截器
axios.interceptors.response.use(
function (response) {
// 2xx 范围内的状态码都会触发该函数。成功进入这个函数
// 对响应数据做点什么
return response;
},
function (error) {
// 超出 2xx 范围的状态码都会触发该函数。失败进入这个函数
// 对响应错误做点什么
// console.dir(error)
if (error.response.status === 401) {
// 说明 token 有问题了(不是忘记携带了,就是token过期了)
location.href = './login.html'
}
return Promise.reject(error);
}
);
略
lineChart(year)
classSalaryChart(salaryData)
-- 右上角饼图sexSalaryChart(salaryData)
-- 左下角原来 那次 调用函数,注释掉
等接口响应数据之后,再调用函数,并且传递实参 groupSalaryChart(groupData)
默认展示1组数据
data: a[1].map(item => item.name)
a[1].map(item => item.hope_salary)
和 a[1].map(item => item.salary)
点击之后,做排他效果
点击之后,设置对应组的数据,并重新创建图表
// 给柱状图上面的 8 个按钮,注册click事件
document.querySelector('#btns').addEventListener('click', function (e) {
if (e.target.tagName === 'BUTTON') {
// 排他效果
document.querySelector('#btns .btn-blue').classList.remove('btn-blue')
e.target.classList.add('btn-blue')
// echarts更换图表数据的步骤【1. 更换图表中x轴、series数据 2. myChart.setOption(option)重新创建图表即可】
// 获取组号
let i = e.target.innerHTML.trim() // trim()是去掉字符串两边的空白
// console.log(i) // 组号有了,每组的数据就是 a[i]
// 换图表配置项中的数据
option.xAxis.data = a[i].map(item => item.name)
option.series[0].data = a[i].map(item => item.hope_salary)
option.series[1].data = a[i].map(item => item.salary)
myChart.setOption(option)
}
})
mapChart(provinceData)
// 在模板数据、接口返回的数据 之后。融合两部分数据
mapData.forEach(item => {
// 判断接口返回的数据有没有北京、河北的、内蒙古的
let 结果 = a.find(v => {
return v.name.includes(item.name)
})
// console.log(结果)
if (结果) {
// item.value = 接口返回的value
item.value = 结果.value
}
})
上述完成
创建新分支,准备开发学生列表页
略
模态框的使用:
let modal = new bootstrap.Modal(盒子)
// 让模态框显示
modal.show()
// 让模态框隐藏
modal.hide()
具体到我们的项目代码:
// --------------------------- 添加学员 -----------------------------------
// 模态框盒子 在 student.html 第 205~285 行
let addModal = new bootstrap.Modal(document.querySelector('#modal'))
// 点击 + 的时候,让模态框显示
document.querySelector('#openModal').addEventListener('click', function () {
addModal.show() // 让模态框显示
})
// 点击模态框中的 确认 按钮
document.querySelector('#submit').addEventListener('click', function () {
addModal.hide() // 让模态框隐藏
})
// --------------------------- 省市县联动 ---------------------------------
let sheng = '<option value="">--省份--</option>'
let shi = '<option value="">--城市--</option>'
let xian = '<option value="">--地区--</option>'
let province = document.querySelector('[name=province]') // 下拉框
let city = document.querySelector('[name=city]')
let area = document.querySelector('[name=area]')
// 获取省,并渲染
axios({
url: '/api/province'
}).then(result => {
// console.log(result)
let newArr = result.data.data.map(item => `<option value="${item}">${item}</option>`)
province.innerHTML = sheng + newArr.join('')
})
// 省切换的时候,获取市,并渲染
province.addEventListener('change', function () {
// console.log(province.value)
area.innerHTML = xian // 切换省的时候,重置区县
axios({
url: '/api/city',
params: {
pname: province.value
}
}).then(result => {
let newArr = result.data.data.map(item => `<option value="${item}">${item}</option>`)
city.innerHTML = shi + newArr.join('')
})
})
// 市切换的时候,获取区县,并渲染
city.addEventListener('change', function () {
axios({
url: '/api/area',
params: {
pname: province.value,
cname: city.value
}
}).then(result => {
let newArr = result.data.data.map(item => `<option value="${item}">${item}</option>`)
area.innerHTML = xian + newArr.join('')
})
})
// 点击模态框中的 确认 按钮
document.querySelector('#submit').addEventListener('click', function () {
// 获取表单各项的值
// let data = val(表单)
let data = val(document.querySelector('#form'))
// 检查是否是接口需要的数据
// console.log(data)
data.age = +data.age
data.group = +data.group
data.gender = +data.gender
data.hope_salary = +data.hope_salary
data.salary = +data.salary
// console.log(data)
// Ajax提交
axios({
method: 'POST',
url: '/students',
data: data
}).then(result => {
// console.log(result)
message.success(result.data.message) // 使用插件提示消息
document.querySelector('#form').reset() // 重置表单
renderStudent() // 更新页面数据
addModal.hide() // 让模态框隐藏
})
})
页面渲染的时候,给 <i>
标签加自定义属性 data-id="${item.id}"
// 找到tbody注册点击事件,里面判断点击的是删除,还是编辑
document.querySelector('tbody').addEventListener('click', function (e) {
if (e.target.classList.contains('bi-trash')) {
// 说明点击了删除
// console.log('你点击了删除')
let id = e.target.dataset.id
// 发送ajax请求,进行删除操作
axios({
url: `/students/${id}`,
method: 'DELETE'
}).then(result => {
// console.log(result)
message.success('删除成功') // 提示
renderStudent() // 更新页面数据
})
}
if (e.target.classList.contains('bi-pen')) {
// 说明点击了编辑
console.log('你点击了编辑')
}
})
点击 + 号的时候,修改模态框的标题:
// 点击 + 的时候,让模态框显示
document.querySelector('#openModal').addEventListener('click', function () {
document.querySelector('.modal-title').innerHTML = '添加学员'
addModal.show() // 让模态框显示
})
点击 编辑 的时候,修改模态框的标题和 属性:
// 找到tbody注册点击事件,里面判断点击的是删除,还是编辑
document.querySelector('tbody').addEventListener('click', function (e) {
// 判断点击的是否是删除 -------------- 略,上一步已经写完了
// 判断点击的是否是编辑
if (e.target.classList.contains('bi-pen')) {
// 说明点击了编辑
// console.log('你点击了编辑')
let id = e.target.dataset.id
document.querySelector('.modal-title').innerHTML = '修改学员'
// document.querySelector('.modal-title').setAttribute('属性名', 值)
document.querySelector('.modal-title').setAttribute('data-id', id)
addModal.show() // 显示模态框
}
})
代码位置:点击 tbody 的时候,判断点击的是 编辑。
// 找到tbody注册点击事件,里面判断点击的是删除,还是编辑
document.querySelector('tbody').addEventListener('click', async function (e) {
if (e.target.classList.contains('bi-trash')) {
// 说明点击了删除
// 代码略。。。。。。。。。。。。。。。。。。。。。。。。。。。。
}
if (e.target.classList.contains('bi-pen')) {
// 说明点击了编辑
// console.log('你点击了编辑')
let id = e.target.dataset.id // 获取编辑按钮的自定义属性值
document.querySelector('.modal-title').innerHTML = '修改学员'
// 下面是设置模态框标题(h5)的自定义属性,值是当前修改的学员的id
// document.querySelector('.modal-title').setAttribute('属性名', 值)
document.querySelector('.modal-title').setAttribute('data-id', id)
addModal.show() // 显示模态框
// 发送请求,获取当前修改的这个学员的详细信息
let result = await axios({ url: `/students/${id}` })
console.log(result.data.data) // 输出的是 个人的详细信息
// 获取城市 和 区县,渲染到第2个和第3个下拉框的位置
let res1 = await axios({
url: '/api/city',
params: {
pname: result.data.data.province
}
})
let res2 = await axios({
url: '/api/area',
params: {
pname: result.data.data.province,
cname: result.data.data.city
}
})
// console.log(res1)
let newArr1 = res1.data.data.map(item => `<option value="${item}">${item}</option>`)
city.innerHTML = shi + newArr1.join('')
// console.log(res2)
let newArr2 = res2.data.data.map(item => `<option value="${item}">${item}</option>`)
area.innerHTML = xian + newArr2.join('')
// 做数据回填,继续使用插件 【 val(表单, 数据) 】,关于这个插件,只是简化代码的步骤。
val(document.querySelector('#form'), result.data.data)
}
})
// 点击模态框中的 确认 按钮
document.querySelector('#submit').addEventListener('click', async function () {
// 获取表单各项的值
// let data = val(表单)
let data = val(document.querySelector('#form'))
// 检查是否是接口需要的数据
// console.log(data)
data.age = +data.age
data.group = +data.group
data.gender = +data.gender
data.hope_salary = +data.hope_salary
data.salary = +data.salary
// console.log(data)
let title = document.querySelector('.modal-title').innerHTML
let result
if (title === '添加学员') {
// Ajax提交,添加数据
result = await axios({
method: 'POST',
url: '/students',
data: data
})
} else if (title === '修改学员') {
// Ajax提交,修改数据
let id = document.querySelector('.modal-title').dataset.id
result = await axios({
method: 'PUT',
url: `/students/${id}`,
data: data
})
}
message.success(result.data.message) // 使用插件提示消息
document.querySelector('#form').reset() // 重置表单
renderStudent() // 更新页面数据
addModal.hide() // 让模态框隐藏
})
退出,和登录是相反的。
登录后,存储了token,跳转到index.html
退出后,移除token,跳转到login.html
common.js中:
// 退出功能
document.querySelector('#logout')?.addEventListener('click', function () {
// 1. 移除token
localStorage.removeItem('token')
// 2. 跳转到登录页
location.href = './login.html' // 路径和JS文件在哪里无关;和html文件有关
})
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。