场景
一个注销页,里面有四种状态。
- 注销说明页
- 输入手机号码和图形验证码
- 输入短信验证码
- 注销处理中
在每一个状态中,都需要被APP调用window.jumpOther()返回到上一个状态
<template>
<div v-if="pageStatus.isDelete"></div>
<div v-if="pageStatus.isInputPhone"></div>
<div v-if="pageStatus.isInputSms"></div>
<div v-if="pageStatus.isSuccess"></div>
</template>
<script setup>
const pageStatus = reactive({
isDelete: true,
isInputPhone: false,
isInputSms: false,
isSuccess: false
})
</script>
问题
一开始使用一层一层手写的方式去进行window.jumpOther()内容改写,导致代码不符合开闭原则
如果这个单页面有大量的状态需要嵌套,这种方法明显是不可行的的
window.jumpOther = () => {
updatePageStatus(pageStatus, 'isInputPhone')
window.jumpOther = () => {
updatePageStatus(pageStatus, 'isDelete')
window.jumpOther = () => {
goSetting()
}
}
}
思路和解决
由于是嵌套,很容易想到递归的思想,利用递归去拼接我们需要的嵌套window.jumpOther()
可以先给出一个状态数组,里面存放了每个状态的名称和对应的jumpOther()方法
const pages = [
{
pageName: 'isDelete',
jumpOther: () => {
console.log(1)
},
},
{
pageName: 'isInputPhone',
jumpOther: () => {
updatePageStatus(pageStatus, 'isDelete')
console.log(2)
},
},
{
pageName: 'isInputSms',
jumpOther: () => {
updatePageStatus(pageStatus, 'isInputPhone')
console.log(3)
},
},
{
pageName: 'isSuccess',
jumpOther: () => {
updatePageStatus(pageStatus, 'isInputSms')
console.log(4)
},
},
]
- 首先我的想法是找到当前状态的位置,然后从当前位置做递减,将所有前列jumpOther进行嵌套。但是这样并不好实现,从而改为从头开始,向上嵌套。
- 然后通过记录当前的window.jumpOther()作为上一次的jumpOther,作为参数传给下一次调用,这样下一次调用将参数(上一次的jumpOther)拼接到自身下
- 传入一个idx作为标识符用来与当前状态的位置作比较,同时作为跳出递归的条件
const updatePageStatus = (statusList, updatedPage) => {
Object.keys(statusList).forEach(s => {
statusList[s] = false
})
statusList[updatedPage] = true
}
const handleSetJumpOther = (lastJump, pageRange, idx) => {
if (pageRange === 0) {
window.jumpOther = pages[idx].jumpOther
return
}
if (idx === pageRange) return
window.jumpOther = () => {
pages[idx].jumpOther()
window.jumpOther = lastJump
}
idx += 1
handleSetJumpOther(window.jumpOther, pageRange, idx)
}
handleSetJumpOther(pages[0].jumpOther, pageRange, 0)
存在问题
- 第一个参数意义为上一次的jumpOther,第一次调用的时候应该传一个空值。但是实际上需要传第一个状态的jumpOther
完整代码
const pageStatus = {
isDelete: false,
isInputPhone: false,
isInputSms: false,
isSuccess: true,
}
const pages = [
{
pageName: 'isDelete',
jumpOther: () => {
console.log(1)
},
},
{
pageName: 'isInputPhone',
jumpOther: () => {
updatePageStatus(pageStatus, 'isDelete')
console.log(2)
},
},
{
pageName: 'isInputSms',
jumpOther: () => {
updatePageStatus(pageStatus, 'isInputPhone')
console.log(3)
},
},
{
pageName: 'isSuccess',
jumpOther: () => {
updatePageStatus(pageStatus, 'isInputSms')
console.log(4)
},
},
]
const findCurrentPageRange = () => {
const currentPage = Object.keys(pageStatus).find(p => {
return pageStatus[p] === true
})
return pages.findIndex(p => {
return p.pageName === currentPage
})
}
const updatePageStatus = (statusList, updatedPage) => {
Object.keys(statusList).forEach(s => {
statusList[s] = false
})
statusList[updatedPage] = true
}
const handleSetJumpOther = (lastJump, pageRange, idx) => {
if (pageRange === 0) {
window.jumpOther = pages[idx].jumpOther
return
}
if (idx === pageRange) return
window.jumpOther = () => {
pages[idx].jumpOther()
window.jumpOther = lastJump
}
idx += 1
handleSetJumpOther(window.jumpOther, pageRange, idx)
}
handleSetJumpOther(pages[0].jumpOther, findCurrentPageRange(), 0)
标签:jumpOther,const,递归,idx,嵌套,window,pageStatus,updatePageStatus,页面 From: https://www.cnblogs.com/karle/p/17983048