封裝vue插件,讀懂這遍文章就夠了

DEMO

麻不燒的Githubjavascript

demo

配合着源碼,用心看完這遍文章,你便領悟了封裝的精髓,麻雀雖小,五臟俱全。css

前記

業務代碼以外的代碼,我想稱之爲增值代碼html

什麼意思?vue

做爲一個程序員,你應該除了完成領導安排的任務,你還應該有一些本身的時間,用來「玩」一些比較有意思的事情。java

當現有框架、庫知足不了咱們需求的時候,咱們應該嘗試去本身造一些工具。也正是這些你所實現的,成就了他人,造就了本身webpack

不信,你且想想,他人會關心你寫的具體的業務邏輯代碼嗎?我想他們更關心的是,你寫的插件,是如何使用的吧,以及方不方便他們藉此完成他們本身業務代碼。git

再通俗一點,他們不會記住你,可是他們會記住你的Api,於是憶起你程序員

還有很重要的一點,全部的技術,都是服務於業務的,不然,就是扯皮。github

背景

入職新公司以來,一直忙於開發業務,過程當中,多處用到了領導寫的牛逼工具。說實話,心裏由衷的佩服,簡直就是解放生產力,放到古代,就是要被封神滴。web

舉個例子:

領導花了一段時間,研究出了一個自動錶單生成器。以前手寫一個表單配置頁,加上表單驗證,可能須要半天,甚至更久。

如今呢?全部的表單、樣式及驗證,均可以經過代碼配置實現,二十分鐘可能就完成了。

由此,我悟出了一個道理:

重複地作一件事,不如用心地作「一件事」。

大海

我想,你確定也想成爲他人口中的那個男人,但成天活在本身的世界裏,你可能一時並不知道該如何去作,這裏我想告訴你:

成長的一個關鍵性因素,就是來自於模仿。

對的,你能夠先嚐試着去閱讀下他人的代碼,看看別人的實現方式,再者能夠去github上溜一圈,優秀項目太多了,仿着寫去唄。

只要你想學,你就必定能學會,只不過是實現的方式好與壞而已,這些是須要後期不斷完善的。

鑑於本遍文章快要跑題了,再也不多述,進入正題...

正文

1.組件和插件的區別與聯繫

區別
  • 組件的使用頻率每每大於插件
  • 組件的做用範圍每每小於插件
聯繫
  • 插件能夠封裝組件,組件能夠暴露數據給插件

這裏不作過多闡述,有興趣能夠參考下勞卜大大的這編文章,寫的很通俗易懂。

2.實現插件的必備因素

基礎

你須要清楚的知道vue的一些高階知識點以及相關內容,好比

  • Vue.extend構造器
  • $mount手動掛載實例
  • mixin混合注入
  • 父子組件傳參、跨級組件傳參
  • 理解Vue構造函數及prototype原形對象
  • npm官網註冊帳號
  • webpack打包
  • ...
技巧

如下這個技巧是今天開發的時候悟出來的,目測頗有用:

彆着急開發,先想着如何在開發中使用你的插件

什麼意思?順着個人思路捋下去


由於我想實現一個全局toast插件,大概用法

this.$toast('那個男人')
    // todo
複製代碼

光彈出文案不行,應該有一個控制彈出方向的變量

this.$toast('那個男人',{
        position:'topCenter'
    })
複製代碼

全局toast的狀態應該有多種,好比常見的成功錯誤警告普通...

// 成功success
    // 錯誤error
    // 警告warning
    // 普通info
    this.$toast('那個男人',{
        position:'topCenter',
        type:'success'
    })
複製代碼

應該有一個時間變量去控制多長時間自動消失toast

this.$toast('那個男人',{
        position:'topCenter',
        type:'success',
        closeTime: 3 // 控制3秒後消失toast
    })
複製代碼

會不會存在一種業務場景,咱們不須要自動消失toast

this.$toast('那個男人',{
        position:'topCenter',
        type:'success',
        closeTime: 3 // 控制3秒後消失toast
        autoClose: false
    })
複製代碼

若是我想在toast結束後,觸發一些回調動做,好比刪除成功toast後刷新列表頁面

this.$toast('那個男人',{
        position:'topCenter',
        type:'success',
        closeTime: 3 // 控制3秒後消失toast
        autoClose: true,
        callback () {
            ...
        }
    })
複製代碼

toast的內容,可能會很長,所以應該有兩個變量分別控制toast寬度和高度

this.$toast('那個男人',{
        position:'topCenter',
        type:'success',
        closeTime: 3 // 控制3秒後消失toast
        autoClose: true,
        callback () {
            ...
        },
        width:300,
        height:80
    })
複製代碼

至此,基礎功能應該都涵蓋了,這個時候你要去考慮一些內建的問題

  1. 這麼多配置項,我做爲一個使用者,都關心嗎?或者說,都須要配置嗎?
  2. 針對不一樣的狀態(success/error/warning/info),確定要用不一樣的顏色區分,以及使用不一樣的圖標,他們之間有什麼關係嗎?
配置項多應該怎麼解決-默認值

默認給個type唄,好比個人項目中默認的type是info,當我在使用的時候,沒有傳入type時,默認爲info

由於大部分的toast場景都是短暫的停留在頁面,因此autoClose設置爲true

又由於大部分的toast文案比較短,因此個人默認toast長寬設置爲300、80應該足夠了

...

以上默認配置,均可以在使用的時候,傳入參數覆蓋默認參數

針對不一樣的狀態,toast圖標、顏色、標題之間有什麼聯繫?

本地存一個map映射配置表,根據傳入的type,我就能夠準確的知道圖標、顏色、標題應該是什麼

map

總結幾點:

  • 插件對外暴露的參數應保持最少原則,聚焦使用者關注點
  • 插件或組件的實現應該要基於使用場景考慮
  • 開發一款組件或者插件,應該保持軟件工程領域的開放封閉原則
  • 一款好的插件或組件並非一蹴而就的,每每須要後期使用過程當中發現問題,加以完善
  • 組件或者插件的文檔必定要完善,並非每個使用它的人,都關心它的內部實現,他們更關心的可能僅是如何快速上手
實現

上文提到過,組件能夠暴露數據給插件,對於這句話

個人理解是,組件是靜態的,只是對外暴露一些參數入口props。 插件,讓咱們能夠動態的往其中注入一些自定義參數。具體的實現,仍是在組件當中完成。

因而乎:我寫了一個靜態組件,經過props定義上文提到的相關變量

先看下script部分

script

再來看下html部分

html

能夠看到,內部實現其實很簡單,無非就是經過外部傳入的props,控制內部的展現細節而已

到這裏靜態組件基本已經完成了(css樣式代碼不在這裏貼了)

注意:

  • props定義的時候,最好用對象的寫法,做爲必定的約束
  • 變量名字最好作到見名知意
  • class名的綁定能夠充分利用vue提供的數組以及對象形式或者配合計算屬性完成

靜態組件怎麼變成插件使用呢?

這裏再也不作過多闡述,vue封裝插件的經常使用方法主要有如下四種,有疑惑的話,建議觀閱vue開發插件固然我以爲你應該還須要去了解下Vue.extend的用法,插件的實現離不開它哦。

看下關鍵部分:該文件也是咱們後期webpack打包(build)的入口文件

config

該文件內容涉及到的知識點,也是開發一個vue插件最核心的內容。裏面的每一行代碼,都充滿了殺機~

至此,關於插件實現部分基本已經所有完成。

3.如何將本身的插件上傳到npm上去

這裏的話,網上的教程有不少,我理解你只須要了解如下幾行代碼的做用,就足夠了

// webpack.config.js
 
 module.exports = {
  entry: process.env.NODE_ENV === 'development' ? './src/main.js' : './src/index.js',
  output: {
    path: path.resolve(__dirname, './dist'),
    publicPath: '/dist/',
    filename: 'build.js',
    libraryTarget: 'umd'
  },
  ...
  
  // package.json
  {
  "name": "mbs-toast",
  "description": "a toast plugin base on Vue2",
  "version": "1.0.0",
  "author": "xxx <xxx88888@163.com>",
  "license": "MIT",
  "private": false,
  "main": "dist/build.js",
  "scripts": {
    "dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
    "build": "cross-env NODE_ENV=production webpack --progress --hide-modules",
    ...
複製代碼
  • 這裏的entry入口文件配置的意思是,開發環境時,入口文件用main.js(方便開發調試使用),打包時入口文件爲index.js
  • filename是打包生成文件的名字,這裏是webpack-simple模版默認使用的就是build.js,沒有特殊需求的話,不建議改動
  • libraryTarget屬性可能你們都會比較陌生,由於通常若是隻在項目中使用 webpack 不須要關注這兩個屬性,可是若是是開發類庫、插件,那麼這兩個屬性就是必須瞭解的,不清楚的能夠參考詳解webpack中ibraryTarget屬性
  • package.json文件中的main字段,指定了該npm包引用的入口(記住必定要記得添加,而且文件名應與上面第二點提到的保持一致)

這裏我用的模版是本身在官方webpack-simple模版的基礎上作了一些定製化的,裏面爲了方便我平時開發,加入了scss、eslint,這樣的話,後面就不用每次手動install了,有興趣的能夠看下README,定製一份屬於本身的腳手架模板

在你瞭解了上述背景後,你只須要執行如下幾步便可實現皆大歡喜

steps

順利的話,如今你已經能夠在正式項目中,經過

npm install -S xxx 安裝你的私有包了
複製代碼

最後在你的入口文件註冊你的插件

import toastPlugin from 'xxx'

Vue.use(toastPlugin) // 這裏Vue.use的第二個參數,能夠經過全局配置,作一些自定義配置,有須要的自行前往學習
複製代碼

到這裏,全部的一切,已塵埃落定

你能夠在代碼中愉快的使用了

this.$toast('塵埃落定', {
    callback () {
      console.log('hello world')
    },
    type: 'success',
    // position: 'topRight',
    autoClose: false
})
複製代碼

最後

我在寫這個插件以前,在Github上看到一個大神封裝的插件。四個字描述下,歎爲觀止,有興趣的必定要去看下,我相信愛學習的你,必定會收穫滿滿。同時在開發該插件時,一些樣式及動畫,也作了相應的參考。

該插件的源碼已經上傳麻不燒的Github,方便你們參考。同時,上述提到的form表單生成器,我也嘗試着本身實現了一遍,有興趣的能夠一塊兒加入哦。戳我快速進入form表單驗證

README後續完善中,理科生畢業,文筆很差,勿噴~

碼字不易,且行且珍惜!

相關文章
相關標籤/搜索