設計模式在vue中的應用(三)

hailx發表於2019-01-27

前言

目錄整理:
設計模式在vue中的應用(一)
設計模式在vue中的應用(二)
設計模式在vue中的應用(三)
設計模式在vue中的應用(四)
設計模式在vue中的應用(五)
設計模式在vue中的應用(六)
設計模式在vue中的應用(七)

為什麼要寫這些文章呢。正如設計模式(Design Pattern)是一套被反覆使用、多數人知曉的、經過分類的、程式碼設計經驗的總結(來自百度百科)一樣,也是想通過分享一些工作中的積累與大家探討設計模式的魅力所在。
在這個系列文章中為了輔助說明引入的應用場景都是工作中真實的應用場景,當然無法覆蓋全面,但以此類推也覆蓋到了常見的業務場景



策略模式應該是我們接觸比較多的幾個設計模式中的一個了,先看一下定義:
(來自百度百科)

  • 定義了一組演算法(業務規則);
  • 封裝了每個演算法;
  • 這族的演算法可互換代替(interchangeable)

一、場景需求

設計模式在vue中的應用(三)
使用者登入系統後有一個狀態標記status對應上圖4種操作提示。

二、分析

使用者登入進來看status的值:

  • 0 —— 未認證
  • 1 —— 認證中
  • 2 —— 認證通過
  • 3 —— 認證不通過

很明顯我們需要根據status的值實現不同的渲染和操作

三、設計

// context.vue
<template>
  <!-- 根據策略規則動態渲染元件 -->
  <component :is="authCom" />
</template>
<script>
  import Need from './Need'
  import Pend from './Pend'
  import Pass from './Pass'
  import Refuse from './Refuse'
  
  const AUTH_STATUS_NEED = 0
  const AUTH_STAUTS_PEND = 1
  const AUTH_STATUS_PASS = 2
  const AUTH_STATUS_REFUSE = 3
  
  export default {
    data () {
      status: AUTH_STATUS_NEED // 通過請求api賦值
    },
    computed () {
      authCom () {
        const statusMap = {
          [AUTH_STATUS_NEED]: Need,
          [AUTH_STAUTS_PEND]: Pend,
          [AUTH_STATUS_PASS]: Pass,
          [AUTH_STATUS_REFUSE]: Refuse
        }
        // 應用策略
        return statusMap[this.status]
      }
    },
    components: {
        Need,
        Pend,
        Pass,
        Refuse
    }
  }
</script>
複製程式碼
// Need.vue
// Pend.vue
// Pass.vue
// Refuse.vue
... do something
複製程式碼

四、還能做點什麼

策略模式一個很明顯的特點就是我們封裝好了一系列演算法策略,context負責組織和按需呼叫這些演算法。

還是上面的場景,使用者的認證狀態每次只會有一個,我們上面封裝了4個演算法並且全部被import,也就是載入了很多無用的程式碼

策略模式配合vue的非同步元件按需載入所需的程式碼

// context.vue
<template>
  <!-- 根據策略規則動態渲染元件 -->
  <component :is="authCom" />
</template>
<script>
  const AUTH_STATUS_NEED = 0
  const AUTH_STAUTS_PEND = 1
  const AUTH_STATUS_PASS = 2
  const AUTH_STATUS_REFUSE = 3
  
  export default {
    data () {
      status: AUTH_STATUS_NEED // 通過請求api賦值
    },
    computed () {
      authCom () {
        const statusMap = {
          [AUTH_STATUS_NEED]: () => ({
            // copy自vue文件
            component: import('./Need'),
            loading: LoadingComponent,
            error: ErrorComponent,
            delay: 200,
            timeout: 3000
          }),
          [AUTH_STAUTS_PEND]: '同上',
          [AUTH_STATUS_PASS]: '同上',
          [AUTH_STATUS_REFUSE]: '同上'
        }
        // 應用策略
        return statusMap[this.status]
      }
    },
    components: {
        Need,
        Pend,
        Pass,
        Refuse,
        LoadingComponent,
        ErrorComponent
    }
  }
</script>
複製程式碼

當然本文舉例的需求和策略實現比較簡單,最終選擇同步打包

總結

策略模式本身理解起來比較簡單,而且這也是我們在業務程式碼中常見的幾個設計模式之一。再次思考下它的應用場景:

遊戲我們都玩過,一個角色他的武器裝扮是刀,那麼它的攻擊動作是砍;
武器裝扮是劍,那麼它的攻擊動作是刺;
武器裝扮是槍,那麼攻擊動作是射擊。

一款遊戲一個重要的特性就是玩法的多樣性,隨著遊戲玩法的豐富武器裝扮和攻擊動作也會越來越多樣化
最終在我們的code中不可能通過ifelse這樣的邏輯判斷來管理我們的邏輯
複製程式碼

結合一個簡單的場景需求,分享了一點經驗希望對你有幫助


本文實現同樣適用於react,為什麼文章以vue做題?vue的template讓我們在理解一些概念的時候可能會有點不適應,而react的jsx可以看做就是在寫JavaScript對各種概念實現更靈活
友情提示:設計模式在vue中的應用應該會寫一個系列,喜歡的同學記得關注下

相關文章