https://www.cnblogs.com/chaoyuehedy/p/9638848.html
let getFileTypesUrl = `${context.contextPath}/projectfile/getAllFileTypes?p_no=` + this.state.projectNo;
//调用方法
this.getFileTypes(getFileTypesUrl)
getFileTypes(url) {
fetch(url,
{
method: "GET"
})
//后台请求的响应结果 data:请求到的数据,类似于ajax
.then((response) => response.json())
.then((data) => {
let list = [];
if (data !== null && data !== undefined) {
data.forEach((item, index, arr) => {
let obj = {value: item, text: item};
list.push(obj);
});
this.state.fileTypes = list;
}
})
}
同步:
homePage.js
法一:回调
import {ewdUrl,fnNewToken, fnNewToken2} from "./util/util";
getNewToken2() {
let that = this
fnNewToken2((newToken)=>{
console.log("myfunc",newToken)
that.setState({
token: Boolean(newToken) ? newToken : localStorage.getItem("jwtToken")
})
});
// console.log('newToken===', newToken)
}
法二:
async getNewToken() {
let newToken = await fnNewToken();
console.log('newToken===', newToken)
this.setState({
token: Boolean(newToken) ? newToken : localStorage.getItem("jwtToken")
})
}
util.js
法一:回调
export let fnNewToken2 = function (myfunc) {
let newToken = '';
let tokenURL = casUrl + "/cas/jwt/token";
fetch(tokenURL, {
method: 'GET',
credentials: 'include',
headers: {
'Content-Type': 'application/x-www-form-urlencoded;'
}
}).then(resp => resp.json()).then(resp => {
if (resp) {
if (resp.status === true) {
newToken = resp.jwtToken;
if(myfunc){
console.log("util token", newToken)
localStorage.removeItem("jwtToken");
localStorage.setItem("jwtToken", newToken)
myfunc(newToken)
}
} else {
console.log('token校验失败')
}
}
})
};
法二:
export let fnNewToken = async function () {
let tokenURL = casUrl + "/cas/jwt/token";
let response = await fetch(tokenURL, {
method: 'GET',
credentials: 'include',
headers: {
'Content-Type': 'application/x-www-form-urlencoded;'
}
})
let data = await response.json();
console.log("=====data====",data)
if(Boolean(data.status) && data.status === true){
localStorage.removeItem("jwtToken");
localStorage.setItem("jwtToken",data.jwtToken)
localStorage.setItem("refreshToken",data.jwtToken)
return data.jwtToken;
} else{
console.log("token校验失败!")
return null;
}
};
onClick: (item, events) => {
let previewUrl = `${context.contextPath}/projectfile/getFileInfo?fileId=` +rowData.file_id;
this.showModal.call(this,previewUrl);
}
showModal 用call()方法,不用在constructor声明 this.showModal = this.showModal.bind() 直接写该方法内容即可。
该处 使用this.showModal.bind(this)这样的形式不能进入到该方法。
返回上一个url
document.referrer: referrer属性返回载入当前文档的来源文档的URL
window.location.replace(document.referrer);
window.location.reload(document.referrer);
Location 对象方法:
assign() 载入一个新的文档
reload() 重新载入当前文档
replace() 用新的文档替换当前文档
新打开浏览器页签:
window.open(url, ‘_blank’).location;
跳转,去请求后台
window.location = ${context.contextPath}/projectpage/index?p_no=
+p_no;
js存储对象
JavaScript 存储对象
Web 存储 API 提供了 sessionStorage (会话存储) 和 localStorage(本地存储)两个存储对象来对网页的数据进行添加、删除、修改、查询操作。
localStorage 用于长久保存整个网站的数据,保存的数据没有过期时间,直到手动去除。
sessionStorage 用于临时保存同一窗口(或标签页)的数据,在关闭窗口或标签页之后将会删除这些数据。
存储对象方法
方法 描述
key(n) 返回存储对象中第 n 个键的名称
getItem(keyname) 返回指定键的值
setItem(keyname, value) 添加键和值,如果对应的值存在,则更新该键对应的值。
removeItem(keyname) 移除键
clear() 清除存储对象中所有的键
window.localStorage 在浏览器中存储 key/value 对。 没有过期时间。
window.sessionStorage 在浏览器中存储 key/value 对。 在关闭窗口或标签页之后将会删除这些数据。
sessionStorage
componentDidMount(){
this.setIndex();
}
setIndex(){
//判断是否存在
// if(!window.sessionStorage) {
if (sessionStorage.getItem("index") != null) {
let indexData = sessionStorage.getItem("index");
//componentDidMount不能用setState ,setState 是异步的 ,想立马看到state修改后的值,这就用到了setState的回调
this.setState({index: indexData}, () => {
console.log('index', this.state.index);
});
}
else {
this.setState({index: 0});
}
// }
}
存:sessionStorage.setItem(“index”,index );
localStorage.setItem(“jwtToken”,jwtToken)
取:sessionStorage.getItem(“index”)
localStorage.getItem(“jwtToken”) 移除:
localStorage.removeItem(“jwtToken”)
使用cookie存储用户信息:
session/cookie 是用于存储用户相关信息的数据存储形式
session存储在服务器保存的是对象,而cookie存储在浏览器本地保存的是字符串
由于session是存储在服务器,会占用服务器资源,一般来说小型项目使用cookie的较多
1.下载cookie相关的包
npm install react-cookies --save
2.cookie知识储备
引用
import cookie from 'react-cookies'
3、存; 设置cookie,第三个参数的意思是所有页面都能用这个cookie
cookie.save(key,value,{path:"/"})
4、取
cookie.load('userId')
5、删
cookie.remove('userId')
6、设置失效
let inFifteenMinutes = new Date(new Date().getTime() + 24 * 3600 * 1000);//一天
cookie.save('userId', "123",{ expires: inFifteenMinutes });
根据以上存取cookie的格式,可以写出cookie.js
import cookie from 'react-cookies'
获取当前用户cookie
export const loginUser = () => {
return cookie.load('userInfo')
}
用户登录,保存cookie
export const onLogin = (user) => {
cookie.save('userInfo', user, { path: '/' })
}
用户登出,删除cookie
export const logout = () => {
cookie.remove('userInfo')
window.location.href = '/Login'
}
以学生管理系统为例,未登录(无cookie时)pathname为’/‘时,跳转到Login进行登录,登录后跳转到对应权限页面。已登录(有cookie存储时)pathname为’/'时,跳转到当前用户对应的权限主页面
import React, { Component } from 'react'
import { Router, Route, Switch } from 'react-router-dom'
import { createBrowserHistory } from 'history'
import { loginUser } from './cooike' // 引入
import {
StudentLayout, TeacherLayout, AdminLayout, Login,
} from './pages' // 导入页面
import NotFound from './components/Common/NotFound'
import Loading from './components/Common/Loading'
const browserHistory = createBrowserHistory() // 路由分发
class BasicRoute extends Component {
render () {
const userInfo = loginUser()
if (userInfo && window.location.pathname === '/') {
if (userInfo.accountRole === 0) {
window.location.href = '/Admin'
} else if (userInfo.accountRole === 1) {
window.location.href = '/Teacher'
} else if (userInfo.accountRole === 2) {
window.location.href = '/Student'
}
}
return (
{
!loginUser()
?
: (
<>
>
)
}
)
}
}
export default BasicRoute
react-cookie官网实例: https://www.npmjs.com/package/react-cookies
补充:
用户登出,删除cookie
export const logout = () => {
cookie.remove('userInfo')
window.location.href = '/Login'
}
如果未在cookie.remove()方法中指定path,那么并不会完全登出当前账号,比如在/Admin/Personal/Add路径下点击退出按钮,并不会如预期登出,解决这个问题的办法就是,在cookie.remove()方法中设定path
用户登出,删除cookie
export const logout = () => {
cookie.remove('userInfo', { path: '/' })
window.location.href = '/Login'
}
就可以解决cookie并未清除的问题了
关于react生命周期 https://www.runoob.com/react/react-component-life-cycle.html
组件的生命周期可分成三个状态:
生命周期的方法有:
componentWillMount 在渲染前调用,在客户端也在服务端。 componentDidMount :
在第一次渲染后调用,只在客户端。之后组件已经生成了对应的DOM结构,可以通过this.getDOMNode()来进行访问。
如果你想和其他JavaScript框架一起使用,可以在这个方法中调用setTimeout,
setInterval或者发送AJAX请求等操作(防止异步操作阻塞UI)。 componentWillReceiveProps
在组件接收到一个新的 prop (更新后)时被调用。这个方法在初始化render时不会被调用。 shouldComponentUpdate
返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。可以在你确认不需要更新组件时使用。
componentWillUpdate在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用。
componentDidUpdate 在组件完成更新后立即调用。在初始化时不会被调用。 componentWillUnmount在组件从
DOM 中移除之前立刻被调用。
https://segmentfault.com/a/1190000015463599?utm_source=tag-newest
1)this.state通常是用来初始化state的,this.setstate是用来修改state值的。如果你初始化了state之后再使用this.state,之前的state会被覆盖掉,如果使用this.setState,只会替换掉相应的state值。
2)this.setState({})会触发render方法,重新渲染界面。而this.state.xxx=’’ 不会重新加载UI。
3)this.setState({})是异步的。
https://blog.csdn.net/weixin_43199050/article/details/93098980
解决方法:(原因不太清楚)
// props改变时 更新state
componentWillUpdate(nextProps, nextState, nextContext) {
// 先比较值是否一样
if (this.state.pass !== nextProps.pass) {
this.setState({
pass: nextProps.pass
})
}
}
父组件给子组件传参:
// 父组件中 SpotInspector为子组件名
status 即 参数名
// 子组件使用props接收父组件传过来的参数
constructor(props) {
super(props);
this.state = {
status: this.props.status,
}}
在父页面第一次渲染时,即把status传给子组件了,
此时子组件拿到的是父组件里设置的this.state.status的默认值(比如 默认值为’’)
在父组件通过接口拿到数据后 再次渲染页面,会把新值传给子组件
此时子组件中的this.props.status值即随之改变。
但是在constructor中的state不会更新
在子页面中回显该值时 需要使用 this.props.status
父组件中该值改变时,给子组件传的参数 props.status也会随之改变,但是子组件中的state不会改变。
所以子页面中回显时需要使用this.props.status
这样会有一个别的问题,比如提交数据时 使用的 this.state.status,但是在父组件的值改变时,state不会随之更新(此时state的值是初始化的值)
只有在该input框更改时 触发onChange方法时会更新state,如果当前没有修改input框内容时,state不会更新,因此 可以通过将 下一次props中的值(这个为第二次渲染时拿到的新值)和state进行比较
// props改变时 更新state
componentWillUpdate(nextProps, nextState, nextContext) {
// 先比较值是否一样
if (this.state.pass !== nextProps.pass) {
this.setState({
pass: nextProps.pass
})
}
}
子组件给父组件传值:
https://www.jianshu.com/p/ccc15c5963c4
onToggle={(t) => {
console.log('t',t)
if(dropdownStyle === "class2"){
document.querySelectorAll('.class2 .epm-menu_item-title').forEach(el =>{ if (el.innerText.indexOf('item2') > -1 ){el.style.color = 'red'}})
} else{
document.querySelectorAll('.class1 .epm-menu_item-title').forEach(el =>{ if (el.innerText.indexOf('item2') > -1 || el.innerText.indexOf('item1') > -1){el.style.color = 'red'}})
}
}}
1)定义
//使用function定义的函数
function foo(){
console.log(this);
}
// 箭头函数
var obj = { aa: foo };
foo(); //Window
obj.aa() //obj { aa: foo }
2)this指向
使用function定义的函数中this指向是随着调用环境的变化而变化的。
使用箭头函数的时候,this的指向是没有发生变化的。
3)构造函数
function是可以定义构造函数的,而箭头函数是不行的。
4)变量提升
由于js的内存机制,function的级别最高,而用箭头函数定义函数的时候,需要var(let const定义的时候更不必说)关键词,而var所定义的变量不能得到变量提升,故箭头函数一定要定义于调用之前!
foo(); //123
function foo(){
console.log('123');
}
arrowFn(); //Uncaught TypeError: arrowFn is not a function
var arrowFn = () => {
console.log('456');
};
方式 一:
通过params
1.路由表中
2.Link处
1)HTML方式
XXXX
2)JS方式
this.props.history.push( '/sort/'+'2' )
3.sort页面
通过 this.props.match.params.id 就可以接受到传递过来的参数(id)
方式 二:
通过query
1、前提:必须由其他页面跳过来,参数才会被传递过来
注:不需要配置路由表。路由表中的内容照常:
2、Link处
1)HTML方式
2)JS方式
this.props.history.push({ path : ‘/sort’ ,query : { name: ’ sunny’} })
3、sort页面
this.props.location.query.name
方式 三:
通过state
1、同query差不多,只是属性不一样,而且state传的参数是加密的,query传的参数是公开的,在地址栏
2、Link 处
1)HTML方式:
2)JS方式:
this.props.history.push({ pathname:'/sort',state:{name : 'sunny' } })
3、sort页面
this.props.location.state.name
1、安装依赖
npm install js-export-excel
2、引入依赖
import ExportJsonExcel from 'js-export-excel';
3、使用
downloadTest(){
const option = {};
// 文件名字
option.fileName = '输煤系统报表';
// 文件的数据集
option.datas = [
{
// 通常用来放我们的表格数据
sheetData: this.state.tableItems,
// sheet名字
sheetName: 'sheet',
// 第一行
sheetHeader: ['设备名称','纵向撕裂1','纵向撕裂2','跑偏跳闸','速度跳闸','跑偏报警','速度报警'],
//列宽 需与列顺序对应, 需要则写
// columnWidths: []
}
]
const toExcel = new ExportJsonExcel(option);
let file = toExcel.saveExcel()
}
安装moment依赖
npm install moment --save
引入moment依赖
import moment from ‘moment’
使用
//获取 当前时间
moment().format('YYYY-MM-DD HH:mm:ss'); //2020-08-25 10:23:59
//获取年份
moment().year(); //2020
moment().get('year'); //2020
//获取月份(0:一月份 11: 12月份 )
moment().month(); //7
moment().get('month'); //7
//获取一个月的某一天
moment().date(); //25
moment().get('date'); //25
//获取小时
moment().hours(); //11
moment().get('hours'); //11
//获取分钟
moment().minutes(); //11
moment().get('minutes'); //11
//获取秒数
moment().seconds(); //17
moment().get('seconds'); //17
//获取 今天星期几
moment().format('dddd'); //Tuesday
moment().format('d'); //2
moment().day(); //2(0~6 分别代表周日到周六)
moment().weekday(); //2(0~6 分别代表周日到周六)
moment().isoWeekday(); //2(1~7 分别代表周一到周日)
moment().get('date'); //2
moment().get('weekday'); //2
moment().get('isoWeekday'); //2
设置时间
//设置年份
moment().year(2019);
moment().set('year', 2019);
moment().set({year: 2019});
//设置月份
//0~11, 0: 1月份, 11: 12月份
moment().month(8);
moment().set('month', 8);
格式化时间
//格式化指定时间
moment(time).format('YYYY-MM-DD');
时间差
now_time.diff(start_time,"hour"); //小时数
now_time.diff(start_time,"minute"); //分钟数
now_time.diff(start_time,"second"); //现在和初始时间相差的秒数
now_time.diff(start_time, 'months'); //月数
now_time.diff(start_time, 'weeks'); //周数
now_time.diff(start_time, 'days'); //天数
相对时间
//add 加时间
//subtract 减时间
moment().subtract(10, 'days').format('YYYY-MM-DD HH:mm:ss'); //2020-08-15 10:51:48
moment().subtract(6, 'days').format('YYYY-MM-DD HH:mm:ss'); //2020-08-19 10:51:48
moment().subtract(3, 'days').format('YYYY-MM-DD HH:mm:ss'); //2020-08-22 10:51:48
moment().subtract(1, 'days').format('YYYY-MM-DD HH:mm:ss'); //前一天:2020-08-24 10:51:48
moment().format('YYYY-MM-DD HH:mm:ss'); //当前时间:2020-08-25 10:51:48
moment().add(1, 'days').format('YYYY-MM-DD HH:mm:ss'); //后一天:2020-08-26 10:51:48
moment().add(3, 'days').format('YYYY-MM-DD HH:mm:ss'); //2020-08-28 10:51:48
moment().add(10, 'days').format('YYYY-MM-DD HH:mm:ss'); //2020-09-04 10:51:48
moment().subtract(1, 'year').format('YYYY-MM-DD HH:mm:ss'); //前一年:
moment().add(1, 'year').format('YYYY-MM-DD HH:mm:ss'); //后一年:
moment().subtract(1, 'hours').format('YYYY-MM-DD HH:mm:ss'); //前一小时:
moment().add(1, 'hours').format('YYYY-MM-DD HH:mm:ss'); //后一小时:
// startOf 设置为起始时间
moment("20111031", "YYYYMMDD").fromNow(); //9 years ago
moment().startOf('day').fromNow(); //11 hours ago
moment().startOf('hour').fromNow(); //an hour ago
moment().endOf('day').fromNow(); //in 13 hours
moment().endOf('hour').fromNow(); //in 15 minutes
//年初
moment().startOf('year').format('YYYY-MM-DD HH:mm:ss'); //2020-01-01 00:00:00
//月初
moment().startOf('month').format('YYYY-MM-DD HH:mm:ss'); //2020-08-01 00:00:00
//日初
moment().startOf('day').format('YYYY-MM-DD HH:mm:ss'); //2020-08-25 00:00:00
//周初 本周第一天(周日)
moment().startOf('week').format('YYYY-MM-DD HH:mm:ss'); //2020-08-23 00:00:00
//本周周一初
moment().startOf('isoWeek').format('YYYY-MM-DD HH:mm:ss'); //2020-08-24 00:00:00
moment().startOf('day').format('YYYY-MM-DD HH:mm:ss') // 当天0点的时间格式
moment().startOf('day').format('X') // 当天0点的时间缀,以10位Unix时间戳输出(秒)
moment().endOf('day').format('YYYY-MM-DD HH:mm:ss') // 当天23点59分59秒的时间格式
moment().endOf('day').format('x') //当天23点59分59秒以13位Unix时间戳输出(毫秒)
moment('2020-06-30').startOf('day').format('x') // 2020-06-30当天0点的以13位Unix时间戳输出(毫秒)
moment('2020-06-30').endOf('day').format('x') // 2020-06-30当天24点的以13位Unix时间戳输出(毫秒)