设计模式在vue中的应用(二)

栏目: 编程语言 · 发布时间: 6年前

内容简介:图片来自iView文档截图在服务端输出页面的开发模式下每完成一步常规做法是跳转一个新页面到下一步,当然在SPA的开发模式下大多场景也是通过路由处理每一步的逻辑。现在的需求是:这整个过程是连续的,除非整个过程处理完成,否则不管进行到哪一步当刷新页面都要从第一步重新开始,也就是在同一个路由下处理这四步操作

图片来自iView文档截图

设计模式在vue中的应用(二)

在服务端输出页面的开发模式下每完成一步常规做法是跳转一个新页面到下一步,当然在SPA的开发模式下大多场景也是通过路由处理每一步的逻辑。

现在的需求是:这整个过程是连续的,除非整个过程处理完成,否则不管进行到哪一步当刷新页面都要从第一步重新开始,也就是在同一个路由下处理这四步操作

二,分析

在文章开头我们提到了状态模式,通过上面的需求我们很容易联想:

  • 第一步操作完成改变状态到第二步
  • 第二步操作完成改变状态到第三步
  • 第三步操作完成改变状态到第四步

三,设计

先看状态模式的介绍

一下内容来自网络

设计模式在vue中的应用(二)

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中的应用(二)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Domain-Driven Design Distilled

Domain-Driven Design Distilled

Vaughn Vernon / Addison-Wesley Professional / 2016-6-2 / USD 36.99

Domain-Driven Design (DDD) software modeling delivers powerful results in practice, not just in theory, which is why developers worldwide are rapidly moving to adopt it. Now, for the first time, there......一起来看看 《Domain-Driven Design Distilled》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

URL 编码/解码
URL 编码/解码

URL 编码/解码

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具