如何正確的(?)利用 Vue.mixin() 偷懶

褲襠三重奏發表於2019-03-02
Vue

前言

最近開發的頁面以及功能大都以表格為主,介面獲取來的 JSON 資料大都是需要經過處理,比如時間戳需要轉換,或者狀態碼的轉義。對於這樣的問題,各大主流框架都提供了類似於過濾的方法,在 Vue 中,一般是在頁面上定義 filter 然後在模板檔案中使用 | 進行處理。

這種方法和以前的遍歷陣列洗資料是方便了許多,但是,當我發現在許多的頁面都有相同的 filter 的時候,每個頁面都要複製一遍就顯的很蛋疼,遂決定用 Vue.mixin() 實現一次程式碼,無限複用

最後,還可以將所有的 filter 包裝成一個 vue 的外掛,使用的時候呼叫 Vue.use() 即可,甚至可以上傳 npm 包,開發不同的專案的時候可以直接 install 使用。(考慮到最近更新的比較快,遂打包上傳這步驟先緩緩,等版本稍微穩定了之後來補全)

正文

閒話說夠,開始正題。

Vue.mixin 為何物

學習一個新的框架或者 API 的時候,最好的途徑就是上官網,這裡附上 Vue.mixin()[點我檢視] 官方說明。

一句話解釋,Vue.mixin() 可以把你建立的自定義方法混入所有的 Vue 例項。

示例程式碼

Vue.mixin({
  created: function(){
    console.log("success")
  }
})
複製程式碼

跑起你的專案,你會發現在控制檯輸出了一坨 success

效果出來了意思也就出來了,所有的 Vue 例項的 created 方法都被改成了我們自定義的方法。

使用 Vue.mixin()

接下來的思路很簡單,我們整合所有的 filter 函式到一個檔案,在 main.js 中引入即可。

在上程式碼之前打斷一下,程式碼很簡單,但是我們可以寫的更加規範化,關於如何做到規範,在 Vue 的官網有比較詳細的 風格指南[點我檢視] 可以參考。

因為我們的自定義方法會在所有的例項中混入,如果按照以前的方法,難免會有覆蓋原先的方法的危險,按照官方的建議,混入的自定義方法名增加字首 $_ 用作區分。

建立一個 config.js 檔案,用於儲存狀態碼對應的含義,將其暴露出去

export const typeConfig = {
  1: "type one",
  2: "type two",
  3: "type three"
}
複製程式碼

再建立一個 filters.js 檔案,用於儲存所有的自定義函式

import { typeConfig } from "./config"
export default {
  filters: {
    $_filterType: (value) => {
      return typeConfig[value] || "type undefined"
    }
  }
}
複製程式碼

最後,在 main.js 中引入我們的 filters 方法集

import filter from "./filters"
Vue.mixin(filter)
複製程式碼

接下來,我們就可以在 .vue 的模板檔案中隨意使用自定義函式了

<template>
  <div>{{typeStatus | $_filterType}}<div>
</template>
複製程式碼

包裝外掛

接下來簡單應用一下 Vue 中外掛的製作方法。建立外掛之後,就可以 Vue.use(myPlugin) 來使用了。

首先附上外掛的 官方文件[點我檢視]

一句話解釋,包裝的外掛需要一個 install 的方法將外掛裝載到 Vue 上。

關於 Vue.use() 的原始碼

function initUse (Vue) {
  Vue.use = function (plugin) {
    var installedPlugins = (this._installedPlugins || (this._installedPlugins = []));
    if (installedPlugins.indexOf(plugin) > -1) {
      return this
    }

    // additional parameters
    var args = toArray(arguments, 1);
    args.unshift(this);
    if (typeof plugin.install === `function`) {
      plugin.install.apply(plugin, args);
    } else if (typeof plugin === `function`) {
      plugin.apply(null, args);
    }
    installedPlugins.push(plugin);
    return this
  };
}
複製程式碼

很直觀的就看到他在最後呼叫了 plugin.install 的方法,我們要做的就是處理好這個 install 函式即可。

上程式碼

config.js 檔案依舊需要,這裡儲存了所有狀態碼對應的轉義文字

建立一個 myPlugin.js 檔案,這個就是我們編寫的外掛

import { typeConfig } from "./config"

myPlugin.install = (Vue) => {
  Vue.mixin({
    filters: {
      $_filterType: (value) => {
        return typeConfig[value] || "type undefined"
      }
    }
  })
}
export default myPlugin
複製程式碼

外掛的 install 函式的第一個引數為 Vue 的例項,後面還可以傳入一些自定義引數。

main.js 檔案中,我們不用 Vue.mixin() 轉而使用 Vue.use() 來完成外掛的裝載。

import myPlugin from "./myPlugin"
Vue.use(myPlugin)
複製程式碼

至此,我們已經完成了一個小小的外掛,並將我們的狀態碼轉義過濾器放入了所有的 Vue 例項中,在 .vue 的模板檔案中,我們可以使用 {{ typeStatus | $_filterType }} 來進行狀態碼轉義了。

結語

Vue.mixin() 可以將自定義的方法混入所有的 Vue 例項中。

本著快速開發的目的,一排腦門想到了這個方法,但是這是否是一個好方法有待考證,雖然不是說擔心會對原先的程式碼造成影響,但是所有的 Vue 例項也包括了第三方模板

本文可以隨意轉載,只要附上原文地址即可。

如果您認為我的博文對您有所幫助,請不吝讚賞,點贊也是讓我動力滿滿的手段 =3=。

待完善

釋出 npm 包

新增項

在 v-html 中騷騷的使用 filter (2018年05月28日)

最近碰到一個問題,也是關於狀態碼過濾的,但是實現的效果是希望通過不同的狀態碼顯示不同的 icon 圖示,這個就不同於上面的文字過濾了,上文使用的 {{ styleStatus | $_filterStyleStatus }} 是利用 v-text 進行渲染,若碰到需要渲染 html 標籤就頭疼了。

按照前人的做法,是這樣的,我隨意上一段程式碼。

...
<span v-if="item.iconType === 1" class="icon icon-up"></span>
<span v-if="item.iconType === 2" class="icon icon-down"></span>
<span v-if="item.iconType === 3" class="icon icon-left"></span>
<span v-if="item.iconType === 4" class="icon icon-right"></span>
...
複製程式碼

不!這太不 fashion 太不 cool,我本能的拒絕這樣的寫法,但是,問題還是要解決,我轉而尋找他法。

在看 Vue 的文件的時候,其中一個 API $options 官方文件[點我檢視] 就引起了我的注意,我正好需要一個可以訪問到當前的 Vue 例項的 API,一拍腦袋,方案就成了。

首先,還是在 config.js 檔案中定義一個狀態碼對應物件,這裡我們將其對應的內容設為 html 段落。

export const iconStatus = {
  1: "<span class=`icon icon-up`></span>",
  2: "<span class=`icon icon-down`></span>",
  3: "<span class=`icon icon-left`></span>",
  4: "<span class=`icon icon-right`></span>"
}
複製程式碼

接著,我們在 filters.js 檔案中引入他,寫法還是和以前的 filters 一樣。

import { iconStatus } from "./config"
export default {
  $_filterIcon: (value) => {
      return iconStatus[value] || "icon undefined"
  }
}
複製程式碼

重頭戲在這裡,我們在模板檔案中需要渲染的地方,使用 v-html 來進行渲染。

<span v-html="$options.filters.$_filterIcon(item.iconType)"></span>
複製程式碼

大功告成,以後需要根據狀態碼來渲染 icon 的地方都可以通過這個辦法來完成了。

事實證明,懶並不一定是錯誤的,關鍵看懶的方向,雖然本篇部落格寫的標題是 偷懶 ,但其實我只是對於重複性的無意義的搬運程式碼而感到厭煩,在尋找對應解決辦法的時候可是一點都沒偷懶,相反的,在尋求更快更好更方便的方法的時候,我逐漸找回了當初敲程式碼的樂趣。

相關文章