本文主要是记录 ANTD Tab 路由
思路主要是两点 左边导航点击后跳转之前把路由存到 session 和 redux 里面
使用的时候先从 redux 里面取,取不出来在从 session 里面取
(1) 左边菜单导航
- 当用户点击左边导航后的事件
handleClick(e) {
console.log(e)
console.log(e.item.props.name)
let name_url = e.item.props.name
//每次取出来urldata
let result = JSON.parse(sessionStorage.getItem('urldata')) || [
{ name: '首页', url: '/admin/home' },
]
let url = e.key
console.log(result)
let count = 0 //计数器,只有找到不同的我才往里面存
result.forEach((item, index) => {
if (item.url !== url) {
count++
}
})
if (count === result.length) {
result.push({ name: name_url, url })
}
//改变REDUX
sessionStorage.setItem('urldata', JSON.stringify(result))
this.props.handleChange(result)
this.props.history.push({ pathname: url })
}
}
- 发送到 redux
import {
CHANGE_VALUE,
CLICK_CHANGE,
DELETE_ITEM,
CHANGE_LOADING,
CHANGE_MENUCOLSPAN,
CHANGE_ROUTER,
DELETE_ROUTER,
CHANGE_ACTIVE_INDEX,
} from './actiontypes'
const defaultState = {
inputValue: '123',
list: [
'Racing car sprays burning fuel into crowd.',
'Japanese princess to wed commoner.',
'Australian walks 100km after outback crash.',
'Man charged over missing wedding girl.',
'Los Angeles battles huge wildfires.',
],
//必须要用的
loadingFlag: false,
menuColSpan: { left: 2, right: 22 },
routerData: [{ name: '首页', url: '/admin/home' }],
activeIndex: 0,
}
export default (state = defaultState, action) => {
//这里判断action的type然后在返回state
if (action.type === CHANGE_VALUE) {
let newresult = JSON.parse(JSON.stringify(state)) //必须要重新生成一个新的对象,也不能使用Object.asign这样有的时候不起作用,而且每个判断里面必须有返回值
newresult.inputValue = action.value
return newresult
}
if (action.type === CLICK_CHANGE) {
let newData = JSON.parse(JSON.stringify(state))
if (newData.inputValue != null) {
newData.list.push(newData.inputValue)
newData.inputValue = ''
}
return newData
}
// 这里就是删除方法,必须返回新数据
if (action.type === DELETE_ITEM) {
let newData = JSON.parse(JSON.stringify(state))
newData.list.splice(action.value, 1)
return newData
}
//----------正式开始------------
if (action.type === CHANGE_LOADING) {
let newData = JSON.parse(JSON.stringify(state))
newData.loadingFlag = action.value
return newData
}
if (action.type === CHANGE_MENUCOLSPAN) {
let newData = JSON.parse(JSON.stringify(state))
newData.menuColSpan = action.value
return newData
}
//改变路由
if (action.type === CHANGE_ROUTER) {
let newData = JSON.parse(JSON.stringify(state))
newData.routerData = action.value
return newData
}
//删除路由
if (action.type === DELETE_ROUTER) {
let newData = JSON.parse(JSON.stringify(state))
newData.routerData.splice(action.value, 1)
return newData
}
if (action.type === CHANGE_ACTIVE_INDEX) {
let newData = JSON.parse(JSON.stringify(state))
newData.activeIndex = action.value
return newData
}
return state
}
(2) 上部 Tab 导航菜单
(i) 第一步取出数据
- 如果说用户刷新了 redux 没了,那我就从 session 里面取
const mapStateToProps = (state) => {
return {
activeIndex:
state.activeIndex === 0
? parseInt(sessionStorage.getItem('urlindex'))
: state.activeIndex,
routerList:
state.routerData.length === 1
? JSON.parse(sessionStorage.getItem('urldata'))
: state.routerData,
}
}
const mapDispatchToProps = (dispatch) => {
return {
handleClick(value) {
const action = ACTION_DELETE_ROUTER(value)
dispatch(action)
},
changeActiveIndex(value) {
console.log('进来了')
sessionStorage.setItem('urlindex', value)
const action = ACTION_CHANGE_ACTIVE_INDEX(value)
dispatch(action)
},
}
}
//最后利用store挂钩
(ii) 第二步渲染数据
这里就是判断当选中的时候两种情况 一种是路由有很多个,另一种是路由只有一个
这里还有一种就是判断当非选中的时候 一种是路由有很多个,另一种是路由只有一个
<ContentHeaderurl>
{routerList.map((item, index) => {
if (index === activeIndex) {
if (index !== 0) {
return (
<div
className="urltab active"
key={index}
onClick={() => {
this.changeUrl(item.url)
}}
>
{item.name}
<span
className="closebutton"
onClick={(e) => {
this.closeUrl(e, index)
}}
>
X
</span>
</div>
)
} else {
return (
<div
className="urltab active"
key={index}
onClick={() => {
this.changeUrl(item.url)
}}
>
{item.name}
</div>
)
}
} else {
if (index !== 0) {
return (
<div
className="urltab"
key={index}
onClick={() => {
this.changeUrl(item.url)
}}
>
{item.name}
<span
className="closebutton"
onClick={(e) => {
this.closeUrl(e, index)
}}
>
X
</span>
</div>
)
} else {
return (
<div
className="urltab"
key={index}
onClick={() => {
this.changeUrl(item.url)
}}
>
{item.name}
</div>
)
}
}
})}
</ContentHeaderurl>
(iii) 第三步依据路由判断是否是当前路由
- 首先通过监听 判断路由是否改变
componentWillReceiveProps(nextProps) {
//监听路由
if (nextProps.location.pathname !== this.props.location.pathname) {
this.setState(
{
nowUrl: nextProps.location.pathname,
},
() => {
this.activeurlnum()
}
)
}
}
- 改变活跃类
activeurlnum() {
let now_url = this.state.nowUrl || this.props.location.pathname //因为刷新,还有点击
console.log(now_url)
let sessionresult = JSON.parse(sessionStorage.getItem('urldata'))
let result_num = 0
for (let i = 0; i < sessionresult.length; i++) {
if (sessionresult[i].url === now_url) {
console.log(i)
result_num = i
}
}
console.log(result_num)
this.props.changeActiveIndex(result_num)
}
- 组件一开始加载的时候执行一次
componentDidMount() {
this.activeurlnum()
}
- 最后点击路由需要跳转
changeUrl(arg) {
console.log(arg)
console.log('改变路由')
this.props.history.push({ pathname: arg })
}
- 点击完以后点击 x 需要关闭路由
closeUrl(e, value) {
e.stopPropagation()
console.log(value)
this.props.handleClick(value)
let sessiondata = JSON.parse(sessionStorage.getItem('urldata'))
sessiondata.splice(value, 1)
sessionStorage.setItem('urldata', JSON.stringify(sessiondata))
//判断选中的条件下删除
if (this.props.activeIndex === value) {
if (sessiondata.length !== 1) {
this.props.history.push({ pathname: sessiondata[value - 1].url })
}
} else {
//非选中的条件下删除
this.activeurlnum()
}
}
mapmutations 里面写
const mapStateToProps = (state) => {
return {
activeIndex:
state.activeIndex === 0
? parseInt(sessionStorage.getItem('urlindex'))
: state.activeIndex,
routerList:
state.routerData.length === 1
? JSON.parse(sessionStorage.getItem('urldata'))
: state.routerData,
}
}
const mapDispatchToProps = (dispatch) => {
return {
handleClick(value) {
const action = ACTION_DELETE_ROUTER(value)
dispatch(action)
},
changeActiveIndex(value) {
console.log('进来了')
sessionStorage.setItem('urlindex', value)
const action = ACTION_CHANGE_ACTIVE_INDEX(value)
dispatch(action)
},
}
}