使用Hook構建解耦的Vue.js應用程序

使用Hook構建解耦的Vue.js應用程序

背景介紹

  • 表單提交時,業務要求對數據埋點以便做數據分析用,對於開發人員來講,實現的方式有多種:
  1. 業務代碼和埋點相關的代碼直接混在一塊兒,這是最直接的實現方式,但也會帶來一些問題,埋點代碼分散在項目的各地方不利於維護,與業務代碼混淆不利於閱讀。
  2. 分離業務代碼和埋點代碼,保持二者的獨立性,能解決方案1中的問題,可是會致使代碼層面複雜些

代碼實現

  • hook.js
const hooks = []

export function addHook (hook) {
  hooks.push(hook)
}

export function runHooks (context) {
  return hooks.filter(hook => hook.condition(context))
               .map(hook => hook.callback(context))
}

export function withHooks (func, context) {
  return (...args) => {
    console.log(args)
    const result = func(...args)

    if (result.then) {
      result
        .then(payload => runHooks({ ...context, payload }))
        .catch(error => runHooks({ ...context, error }))
      return result
    }

    runHooks({ ...context, payload: result })
    return result
  }
}

複製代碼
  • 上面的代碼能夠將Hook對象添加到一個Hooks堆棧中,一旦調用runHooks()就會觸發它們。每一個Hook都是一個具備條件和回調的對象。僅當condition()函數返
  • tracking.js
import { addHook } from '@/utils/hooks'

const CONTACT_FORM = 'contact-form.post'

addHook({
  condition ({ error, id }) {
    return !error && id === CONTACT_FORM
  },
  callback (context) {
    // 用於數據報送、或數據分析的邏輯
    console.log('用於數據報送、或數據分析的邏輯', context)
  }
})

複製代碼
  • 能夠看到咱們添加了一個新的Hook,只有在沒有錯誤而且id context參數與CONTACT_FORM id匹配時纔會觸發。在callback()函數中,咱們一般會在咱們選擇的跟蹤服務中觸發一個事件,但由於這只是一個演示,咱們只需觸發一個console.log()vue

  • 模擬後臺請求 loanApply.js編程

export function post (data) {
  return Promise.resolve(data)
}
複製代碼
  • 組件中使用
<template>
  <form @submit.prevent="submit">
    <label class="contact-form-label">
      Name
      <input v-model="data.name">
    </label>
    <label class="contact-form-label">
      Message
      <textarea v-model="data.message"/>
    </label>
    <button>Submit</button>
  </form>
</template>

<script>
  import './tracking'
  import { post } from '@/api/loanApply'
  import { withHooks } from '@/utils/hooks'

  export default {
    data () {
      return { data: { name: '', message: '' } }
    },
    methods: {
      submit () {
        withHooks(this.test, { id: 'contact-form.post' })(this.data)
      },
      async test (param) {
        const {message, name} = await post(param)
        console.log(message, name, '處理表單自己的業務邏輯')
        return param
      }
    }
  }
</script>

複製代碼

總結

  • 與編程中的其餘的高級模式同樣,hook也有其缺點。首先,它們增長了另外一層複雜性。將跟蹤邏輯直接添加到組件的代碼中雖然不是最乾淨的解決方案,但它絕對是最直接的。特別是若是您的應用程序很是小,使用Hooks可能只會使您的代碼庫更復雜,而不是簡化它。
  • 所以決定是否要實現此模式以前首先考慮全部優勢和缺點。在合適的狀況下。

參考連接

vue中使用鉤子函數解耦業務api

相關文章
相關標籤/搜索