内容简介:图片来自iView文档截图在服务端输出页面的开发模式下每完成一步常规做法是跳转一个新页面到下一步,当然在SPA的开发模式下大多场景也是通过路由处理每一步的逻辑。现在的需求是:这整个过程是连续的,除非整个过程处理完成,否则不管进行到哪一步当刷新页面都要从第一步重新开始,也就是在同一个路由下处理这四步操作
图片来自iView文档截图
在服务端输出页面的开发模式下每完成一步常规做法是跳转一个新页面到下一步,当然在SPA的开发模式下大多场景也是通过路由处理每一步的逻辑。
现在的需求是:这整个过程是连续的,除非整个过程处理完成,否则不管进行到哪一步当刷新页面都要从第一步重新开始,也就是在同一个路由下处理这四步操作
二,分析
在文章开头我们提到了状态模式,通过上面的需求我们很容易联想:
- 第一步操作完成改变状态到第二步
- 第二步操作完成改变状态到第三步
- 第三步操作完成改变状态到第四步
三,设计
先看状态模式的介绍
一下内容来自网络
1,首先需要一个context环境角色
// context.vue <template> <div> <Steps :current="status"> <Step title="已完成" content="这里是第一步"></Step> <Step title="进行中" content="这里是第二步"></Step> <Step title="待进行" content="这里是第三步"></Step> <Step title="待进行" content="这里是第四步"></Step> </Steps> <!-- 动态渲染当前状态组件 --> <component :is="statusCom" @onChangeStatus="changeStatus" /> </div> </template> <script> // 引入各状态组件 import Step1 from './Step1' import Step2 from './Step2' import Step3 from './Step3' import Step4 from './Step4' export default { data() { return { status: 1 } }, computed: { // 具体状态角色 statusCom() { const statusMap = { 1: Step1, 2: Step2, 3: Step3, 4: Step4, } return statusMap[this.status] } }, methods: { // 代表每一步的状态组件都有改变status的能力 changeStatus(val) { this.status = val } } } </script> 复制代码
2,实现State抽象状态角色
// Step1.vue <template> <div> <!-- do something --> <button @click="handleClick">完成</button> </div> </template> <script> export default { methods: { handleClick() { // 第一步完成,将状态变为状态2 // context角色接受状态改变动态渲染Step2.vue的操作 this.$emit('onChangeStatus', 2) } } } </script> 复制代码
Step2.vue Step3.vue Step4.vue 同Step1.vue 复制代码
3,总结
- context角色只负责具体状态的切换——渲染哪一步的组件
- state角色负责处理当前状态的实现和切换下一个状态——每一步逻辑的具体实现
四,优化
通过上面的实现,我们发现整个状态的改变都交给了各状态组件,如果这时我操作到了第3步想回退到第2步怎么办?
给每个状态组件加一个回退到上一个状态的功能?
在我们这个需求中状态从1->2->3->4是单向的,这个方式或许能行,假设在一个比较复杂的状态场景下,各状态的改变毫无章法很难确定当前状态的上一个状态是什么
解决办法:为每一次状态改变做一次缓存
// 优化后的context.vue <template> <div> <Steps :current="status"> <Step title="已完成" content="这里是第一步"></Step> <Step title="进行中" content="这里是第二步"></Step> <Step title="待进行" content="这里是第三步"></Step> <Step title="待进行" content="这里是第四步"></Step> </Steps> <!-- 返回上一步 --> <button v-if="canGoBack" @click="goBack">返回上一步</button> <!-- 动态渲染当前状态组件 --> <component :is="statusCom" @onChangeStatus="changeStatus" /> </div> </template> <script> // 引入各状态组件 import Step1 from './Step1' import Step2 from './Step2' import Step3 from './Step3' import Step4 from './Step4' export default { data() { return { status: 1, cache: [] // 缓存状态 } }, computed: { // 具体状态角色 statusCom() { const statusMap = { 1: Step1, 2: Step2, 3: Step3, 4: Step4, } return statusMap[this.status] }, canGoBack() { return this.cache.length > 0 } }, methods: { // 代表每一步的状态组件都有改变status的能力 changeStatus(val) { // 缓存每一次的状态变化 this.cache.push(val) this.status = val }, goBack() { // 弹出当前状态 this.cache.pop() // 改变状态为上一个状态 this.status = this.cache[this.cache.length] } } } </script> 复制代码
总结
通过工作中的一个功能设计为大家介绍了状态模式。或许有的同学会说我通过 if
else
不也能做吗,当然随着需求不断的变更你的 if
else
最终只有你自己看的懂,慢慢的 bug 出现的几率也越高,状态模式正是用来解决这种问题的
本文实现同样适用于react,为什么文章以vue做题?vue的template让我们在理解一些概念的时候可能会有点不适应,而react的jsx可以看做就是在写JavaScript对各种概念实现更灵活
友情提示:设计模式在vue中的应用应该会写一个系列,喜欢的同学记得关注下
以上所述就是小编给大家介绍的《设计模式在vue中的应用(二)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 设计模式——订阅模式(观察者模式)
- 设计模式-简单工厂、工厂方法模式、抽象工厂模式
- java23种设计模式-门面模式(外观模式)
- 设计模式-享元设计模式
- Java 设计模式之工厂方法模式与抽象工厂模式
- JAVA设计模式之模板方法模式和建造者模式
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。