vue開發插件上傳npm

插件一般用來爲 Vue 添加全局功能,通常有下面幾種:html

  1. 添加全局方法或者屬性。
  2. 添加全局資源:指令/過濾器/過渡等。
  3. 經過全局混入來添加一些組件選項。
  4. 添加 Vue 實例方法,經過把它們添加到 Vue.prototype 上實現。
  5. 一個庫,提供本身的 API,同時提供上面提到的一個或多個功能。

更加詳細說明查看官網文檔 https://cn.vuejs.org/v2/guide...vue

開發插件

1.簡單的插件
建立一個countdown.vuewebpack

<template>
  <div>封裝一個最簡單的插件</div>
</template>
<script>
  export default {
    name: 'count-down'
  }

</script>

建立一個index.jsweb

import countDown from './countdown';

//暴露一個 `install` 方法。這個方法的第一個參數是 `Vue` 構造器,第二個參數是一個可選的選項對象
countDown.install = function (Vue) {
  Vue.component(countDown.name, countDown);
};

export default countDown;

目錄結構爲:
snipaste_20200412_111210.png數組

在main.js中引入,頁面中<count-down></count-down>就能夠使用less

import countDown from './components/global/index';
//經過全局方法 `Vue.use()` 使用插件
Vue.use(countDown);

2.添加全局方法或屬性ide

countDown.install = function (Vue) {
  Vue.prototype.$msg = '全局的屬性';
  Vue.prototype.$myMethod = function () {
    console.log('全局定義的方法');
  }
  Vue.component(countDown.name, countDown);
};

3.添加全局資源函數

countDown.install = function (Vue) {
  //全局自定義指令
  Vue.directive('focus', {
    //當節點插入的時候
    inserted: function (el) {
      el.focus();
    }
  })
  Vue.component(countDown.name, countDown);
};

4.注入組件選項flex

countDown.install = function (Vue) {
  //全局混入
  Vue.mixin({
    created() {
      console.log('i am jello')
    },
  })
  Vue.component(countDown.name, countDown);
};

開發插件進階

建立一個VsButton.vueui

<template>
  <button class="vs-button" :class="type" @click="fn">
    <slot></slot>
  </button>
</template>

<script>
  export default {
    name: 'VsButton',
    props: {
      type: {
        type: String,
        default: 'warning'
      }
    },
    methods: {
      fn() {
        this.$emit('click');
      }
    },
  }

</script>

<style lang='less' scoped>
  .vs-button {
    width: 100px;
    height: 40px;
    background: #ccc;
    border-radius: 4px;
  }

  .warning {
    background: yellow
  }

  .danger {
    background: red
  }

  .success {
    background: green
  }

</style>

建立VsMsg.vue

<template>
  <transition name="fade">
    <div class='vs-msg' v-show='visible'>
      <img src='../../../assets/msg.png' class='pic' />
      <span class='msg-text' @click='close'>
        <slot></slot>
      </span>
    </div>
  </transition>
</template>

<script>
  export default {
    name: 'VsMsg',
    props: {
      visible: {
        type: Boolean,
        default: false
      }
    },
    methods: {
      close() {
        this.$emit('update:visible', false);
      }
    },
  }

</script>

<style lang='less' scoped>
  .vs-msg {
    width: 330px;
    min-height: 280px;
    display: flex;
    flex-direction: column;
    padding: 30px;
    background: #eee;

    .pic {
      width: 100%;
      height: 200px;
    }

    .msg-text {
      height: 80px;
      line-height: 80px;
      background: rgba(255, 255, 255, 1);
      border-radius: 0px 0px 10px 10px;
      font-size: 16px;
      color: rgba(255, 162, 26, 1);
    }
  }

  .fade-enter-active,
  .fade-leave-active {
    transition: opacity .3s ease;
  }

  .fade-enter,
  .fade-leave-to {
    opacity: 0;
  }

</style>

建立一個index.js

import VsMsg from '../plugins/msg/VsMsg';
import VsButton from '../plugins/button/VsButton';

let plugin = {};

plugin.install = function (Vue) {
  Vue.component(VsMsg.name, VsMsg);
  Vue.component(VsButton.name, VsButton);
}

export default plugin;

每次使用都須要import和Vue.component(),可採用webpack的require.context(),實現自動導入和註冊組件。

1)require.context函數接受三個參數:

  • directory {String} -讀取文件的路徑
  • useSubdirectories {Boolean} -是否遍歷文件的子目錄
  • regExp {RegExp} -匹配文件的正則

2)require.context函數執行後返回的是一個函數,而且這個函數有3個屬性

  • resolve {Function} -接受一個參數request,request爲test文件夾下面匹配文件的相對路徑,返回這個匹配文件相對於整個工程的相對路徑
  • keys {Function} -返回匹配成功模塊的名字組成的數組
  • id {String} -執行環境的id,返回的是一個字符串,主要用在module.hot.accept
const requireComponent = require.context('./', true, /\.vue$/); //獲取一個特定的上下文,主要用來實現自動化導入模塊

const install = (Vue) => { 

  if (install.installed) return;
  install.installed;
  requireComponent.keys().forEach(fileName => {
    //第i個組件
    const config = requireComponent(fileName);
    //組件名
    const componentName = config.default.name;

    Vue.component(componentName, config.default || config);
  })

}

//檢測環境
if (typeof window !== undefined && window.Vue) {
  install(Vue);
}

export default install;

在main.js中引入

import index from "./components/plugins/index.js";
Vue.use(index);

頁面中使用插件

<template>
    <VsButton type='warning' @click="open">默認按鈕</VsButton>
    <VsMsg :visible.sync="visible">我是一個消息</VsMsg>
</template>

<script>
  export default {
    data() {
      return {
        visible: false
    },
    methods: {
      open() {
        this.visible = true;
      }
    }
  }
</script>

實現效果以下:
snipaste_20200412_115451.png

相關文章
相關標籤/搜索