記基於Vue.js的UI插件開發併發布到NPM

引言

用過Vue.js開發的童鞋應該都知道ElementUIIviewAnt Design of Vue等UI框架,這些框架給咱們平常的開發帶來巨大的便利,大大提升了開發效率,有不少公司或者項目組也會有屬於本身的UI框架。組件開發在面試中也會被問到,有本身的開源UI框架在面試中也有很多的加分。成就感也天然而然的提升。下面分享一下我最近學習開發的內容。css

開發前需知

咱們使用ElementUI時都知道,導入EelementUI後須要使用Vue.use()才能生效,由於每一個插件都應該暴露一個install方法,install 方法調用時,會將 Vue 做爲參數傳入。Vue.use()也能夠傳入參數,如Vue.use(MyPlugin, { someOption: true })可自定義全局的設置,在Vue官方文檔有關於插件開發的說明,具體可前去學習。html

實現一個Button插件

項目初始化

Vue支持對*.vue文件進行快速原型開發,因此咱們就不用腳手架構建項目了,直接在bash窗口執行如下命令建立項目vue

$ mkdir my-ui
$ cd my-ui
$ npm init -y
複製代碼

在項目中建立如下文件和文件夾,node

Button.vue文件中加入如下代碼git

<template>
    <div>Hello Vue</div>
<template>
複製代碼

要支持Vue原型開發,還須要安裝如下兩個插件github

$ npm install -g @vue/cli
$ npm install -g @vue/cli-service-global
複製代碼

安裝完成後執行npm serve Button.vue打開localhost:8080就能看到‘Hello Vue’,接下來咱們就模仿EelmentUI的Button完成一個Button插件。web

Button內容及樣式

修改Button.vue中template的內容以下:面試

<template>
    <button :class="`tom-button tom-button-${type} tom-button-${size} ${round ? 'tom-button-round': ''} ${disabled ? 'is-disabled' : ''}`" @click="onClick" :disabled="disabled" >
        <slot></slot>
    </button>
</template>
複製代碼

而後js部分經過props對象傳入值,在methods對象添加方法,使用this.$emit傳遞事件。npm

export default {
  name: 'tom-button',
  props: {
    type: {
      type: String,
      default: 'default',
      validator(type) {
        return ['default', 'primary', 'info', 'warning', 'danger'].includes(
          type
        )
      }
    },
    size: {
      type: String,
      default: 'medium',
      validator(size) {
        return ['medium', 'small', 'mini'].includes(size)
      }
    },
    round: {
      type: Boolean,
      default: false
    },
    disabled: {
      type: Boolean,
      defalut: false
    }
  },
  methods: {
    onClick(event) {
      this.$emit('click', event)
    }
  }
}
複製代碼

最後給Button加上因此的樣式json

.tom-button {
      display: inline-block;
      outline: 0;
      font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
      user-select: none;
      cursor: pointer;
      line-height: 1;
      white-space: nowrap;
      background-color: #fff;
      border: 1px solid #dcdfe6;
      color: #606266;
      -webkit-appearance: none;
      text-align: center;
      box-sizing: border-box;
      outline: none;
      margin: 0;
      transition: 0.1s;
      font-weight: 500;
      padding: 12px 20px;
      font-size: 14px;
      border-radius: 4px;
    }

    .tom-button.is-disabled {
      color: #c0c4cc;
      cursor: not-allowed;
      background-image: none;
      background-color: #fff;
      border-color: #ebeef5;
    }

    /*背景顏色*/

    .tom-button-primary {
      color: #fff;
      background-color: #409eff;
      border-color: #409eff;
    }

    .tom-button-primary.is-disabled {
      color: #fff;
      background-color: #a0cfff;
      border-color: #a0cfff;
    }

    .tom-button-success {
      color: #fff;
      background-color: #67c23a;
      border-color: #67c23a;
    }

    .tom-button-success.is-disabled {
      color: #fff;
      background-color: #b3e19d;
      border-color: #b3e19d;
    }

    .tom-button-info {
      color: #fff;
      background-color: #c8c9cc;
      border-color: #c8c9cc;
    }

    .tom-button-info.is-disabled {
      color: #fff;
      background-color: #c8c9cc;
      border-color: #c8c9cc;
    }

    .tom-button-warning {
      color: #fff;
      background-color: #e6a23c;
      border-color: #e6a23c;
    }

    .tom-button-warning.is-disabled {
      color: #fff;
      background-color: #f3d19e;
      border-color: #f3d19e;
    }

    .tom-button-danger {
      color: #fff;
      background-color: #f56c6c;
      border-color: #f56c6c;
    }
    .tom-button-danger.is-disabled {
      color: #fff;
      background-color: #fab6b6;
      border-color: #fab6b6;
    }

    /*Button大小*/
    .tom-button-medium {
      padding: 10px 20px;
      font-size: 14px;
      border-radius: 4px;
    }

    .tom-button-small {
      padding: 9px 15px;
      font-size: 12px;
      border-radius: 3px;
    }

    .tom-button-mini {
      padding: 7px 15px;
      font-size: 12px;
      border-radius: 3px;
    }

    /*是否圓角*/
    .tom-button-round {
      border-radius: 20px;
    }
複製代碼

而後在Btton文件夾中的index.js給組件添加install方法並導出

import TomButton from './Button.vue'

TomButton.install = function(Vue) {
  Vue.component(TomButton.name, TomButton);
};


export default TomButton
複製代碼

最後在src目錄下的index.js中導入Button中的index.js並全局導出。

// 引入組件
import TomButton from './Button/index.js'

const components = [
  TomButton
]

const install = function(Vue, opts) {
  if (install.installed) return
  // 遍歷註冊全局組件
  components.forEach(component => {
    Vue.component(component.name, component);
  });
}

// 用於script標籤引入
if (typeof window !== 'undefined' && window.Vue) {
  install(window.Vue)
}


export default {
  install, 
  TomButton
}
複製代碼

本地測試

到此Button插件就已經完成了,我先在本地測試一下,在根目錄新建app.vue文件,導入Button組件:

<template>
  <div class="home">
	<tom-button size="medium" type="primary" disabled @click="handleClick">按鈕</tom-button>
  </div>
</template>

<script>
import TomButton from './src/Button/Button.vue'
export default {
  components: {
    TomButton
  },
  methods: {
    handleClick() {
      console.log('test')
    }
  }
}
</script>
複製代碼

在命令窗口執行vue serve app.js打開瀏覽器不出意外就會顯示以下的按鈕,鼠標移上去,也有禁用的符號

打包插件

本地測試沒問題後,就能夠打包發佈了。打包工具我使用的是rollup.js,使用它首先須要全局安裝

$ npm install rollup --global
複製代碼

rollup.js默認是不支持打包*.vue文件的,因此要支持打包.vue文件還須要安裝如下的包

$ npm install rollup-plugin-commonjs --save
$ npm install rollup-plugin-vue --save
$ npm install vue-template-compiler --save
複製代碼

而後在根目錄新建配置文件rollup.config.js,並添加配置代碼:

import vue from 'rollup-plugin-vue';
import commonjs from 'rollup-plugin-commonjs';

export default {
  input: 'src/Button/index.js',
  output: {
    file: 'lib/st-vue-ui.js',
    format: 'cjs'
  },
  // 支持.vue文件的打包
   plugins: [
        commonjs(),
        vue(),
    ]
};
複製代碼

接着在package.json文件添加一條命令"build": "rollup -c rollup.config.js",以下圖:

完成後在命令窗口執行npm run build命令,打包完成在根目錄就會生成lib文件夾,裏面的js文件就是打包後的文件。

發佈到npm

打包完成,接下來就能夠發佈到npm上了,是否是想一想還有點小激動。發佈前須要在根目錄新建一個.npmignore文件,這個文件和Git的.gitignore文件同樣,用於過濾不用上傳的文件,.npmignore文件內容以下:

node_modules/
src/
rollup.config.js
app.vue
.gitignore
複製代碼

而後在package.json文件添加一些字段,如下是參考配置,瞭解更多可去npm官網查看

"name": "st-vue-ui",       // 項目名字,npm install + name
 "version": "1.0.3",        // 項目版本號
 "description": "基於Vue的UI插件",      // 項目描述
 "main": "lib/st-vue-ui.js",       //指定了包加載的入口文件,默認值是模塊根目錄下面的index.js
 "private": false,         // 爲false時表明你的包不是私有的,全部人都能查看並npm install使用
 "keywords": ["vue", "UI"],   // 項目關鍵字
複製代碼

爲了讓別人更方便的使用本身插件,咱們能夠加上說明文檔。在根目錄新建README.md文件,對本身的插件進行簡單的介紹,能夠下載typora這個軟件對*.md文件進行編輯。

好了,終於能夠發佈了,發佈到npm須要到npm註冊一個帳號,註冊完成後,回到項目的命令窗口執行npm login,輸入用戶名、密碼、郵箱登陸成功。

而後執行npm publish就能夠發佈了,第一次發佈會遇到報錯,提示須要驗證郵箱。根據提示去郵箱驗證後從新執行npm publish通常均可以發佈成功,如圖:

發佈成功後去本身的主頁下查看就能夠看到了

如今按照跟ElementUI同樣的方法,你能夠在本身的項目中使用了。下次更新發布須要修改版本號打包再上傳,使用的時候把package.json中包名的版本號改成最新的,而後執行npm install後重啓項目就能夠了。

結語

這裏我只作了一個簡單的Button插件,若是再寫一個插件,就在src創建對應的目錄如Input,而後新建Input.vue和index.js,把對應的插件的index.js文件導入便可。搭建一套UI組件庫仍是挺複雜的,不過經過這個小demo應該能夠得到不少的靈感,也對Vue的使用有了更多的學習。目前這個UI框架只能全局引入,不能像ElementUI那樣按需引入。目前沒有太多時間去學習,以後學習了再作更新,若有思路或者作過的童鞋也歡迎留言指導。路過的童鞋不要忘了點贊鼓勵一下哦!

參考文章

Vue.js - 構建你的第一個包並在NPM上發佈

記搭建一個Vue組件庫

項目地址

github地址

npm地址

相關文章
相關標籤/搜索