vue.use()原理和Vue插件的開發使用

參考:

https://cn.vuejs.org/v2/guide/plugins.html

https://juejin.im/post/5d8464a76fb9a06b3260ad30

https://www.cnblogs.com/adouwt/p/9211003.html

一、背景

  1. 爲什麼在引入Vue-Router、ElementUI的時候需要Vue.use()?而引入axios的時候,不需要Vue.use()?  Vue.use()是爲Vue插件(需要依賴vue才能實現)進行初始化的,而axios不用依賴vue也能執行,所以不需要使用Vue.use()進行初始化。
  2. Vue-Router、ElementUI在Vue.use()分別做了什麼?
  3. Vue.use原理
  4. 如何編寫和使用一個Vue插件?

二、vue.use()原理

Vue.use是官方提供給開發者的一個api,用來註冊、安裝類型Vue插件的。

該方法需要在調用 new Vue() 之前被調用。

當 install 方法被同一個插件多次調用,插件將只會被安裝一次。

1.vue.use的使用:

在main.js中調用:

Vue.use(ElementUi);
Vue.use(Vuex);
Vue.use(Router);

 

2.vue.use()原理:

  1. 檢查插件是否安裝,如果安裝了就不再安裝
  2. 如果沒有沒有安裝,那麼調用插件的install方法,並傳入Vue實例
export function initUse (Vue: GlobalAPI) {
  Vue.use = function (plugin: Function | Object) {
    // 獲取已經安裝的插件
    const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
    // 看看插件是否已經安裝,如果安裝了直接返回
    if (installedPlugins.indexOf(plugin) > -1) {
      return this
    }

    // toArray(arguments, 1)實現的功能就是,獲取Vue.use(plugin,xx,xx)中的其他參數。
    // 比如 Vue.use(plugin,{size:'mini', theme:'black'}),就會回去到plugin意外的參數
    const args = toArray(arguments, 1)
    // 在參數中第一位插入Vue,從而保證第一個參數是Vue實例
    args.unshift(this)
    // 插件要麼是一個函數,要麼是一個對象(對象包含install方法)
    if (typeof plugin.install === 'function') {
      // 調用插件的install方法,並傳入Vue實例
      plugin.install.apply(plugin, args)
    } else if (typeof plugin === 'function') {
      plugin.apply(null, args)
    }
    // 在已經安裝的插件數組中,放進去
    installedPlugins.push(plugin)
    return this
  }
}

 

3.創建vue插件

(1)創建plugins文件夾存放插件文件(loading和toast兩個插件)

(2)代碼:loading是通過組件的形式使用,生成在#app中。toast是通過js方法使用,調用後插入#app下方

loading.vue:

<template>
    <div class="nwd-loading" v-show="show">
        <div>{{text}}</div>
    </div>
</template>

<script>
    export default {
        props: ['show', 'text']
    }
</script>

loading.js:

import Loading from './loading.vue'
export default {
	install(Vue,options) {
		Vue.component('loading', Loading);
	}
}

 

toast.vue:

<template>
    <transition name="fade">
        <div class="toast" v-show="show">
            {{message}}
        </div>

    </transition>
</template>

<script>
export default {
  data() {
    return {
      show: false,
      message: "提示框"
    };
  }
};
</script>

<style scoped>
.toast {
  position: fixed;
  top: 40%;
  left: 50%;
  margin-left: -15vw;
  padding: 2vw;
  width: 30vw;
  font-size: 4vw;
  color: #fff;
  text-align: center;
  background-color: rgba(0, 0, 0, 0.8);
  border-radius: 5vw;
  z-index: 999;
}

.fade-enter-active,
.fade-leave-active {
  transition: 0.3s ease-out;
}
.fade-enter {
  opacity: 0;
  transform: scale(1.2);
}
.fade-leave-to {
  opacity: 0;
  transform: scale(0.8);
}
</style>

toast.js:

import Toast from './toast.vue'

export default {
	install(Vue, options) {
		// 生成一個Vue子類
		const toast = Vue.extend(Toast);

		// 生成該子類的實例
		let toastInstance = new toast();
		console.log(toastInstance);

		// 將實例掛載到新創建的div上
		toastInstance.$mount(document.createElement('div'));

		// 將此div加入全局掛載點內部,#app下方
		console.log(toastInstance.$el);
		document.body.appendChild(toastInstance.$el);

		// 通過Vue註冊一個原型方法
		// 所有實例共享這個方法
		Vue.prototype.$toast = (msg, duration = 2000) => {
			toastInstance.message = msg; 
			toastInstance.show = true;
			setTimeout(()=>{
				toastInstance.show = false;
			}, duration);
		}
	}	
}

main.js引入:

import Vue from 'vue'
import App from './App'
import router from './router'
import Loading from './plugins/loading/loading.js'
import Toast from './plugins/toast/toast.js'

Vue.use(Loading)
Vue.use(Toast)


Vue.config.productionTip = false

/* eslint-disable no-new */
var vue1 = new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

HelloWorld.vue組件使用

<template>
  <div class="hello">
    <!-- 使用loading -->
    <loading :show="show" :text="msg"></loading>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      show:true,
      msg: 'I am loading'
    }
  },
  created() {
    // 使用toast
    this.$toast('司法局防輻射服', 30000);
  }
}
</script>

 

三、插件打包併發布

1.新建一個項目:test-toast

vue init webpack-simple 項目名
cd test-toast
npm install //安裝依賴

2.將上面的toast.js和toast.vue放入src目錄中,toast.js重命名爲index.js

 3.修改webpack.config.js:

  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, './dist'),
    publicPath: '/dist/',
    filename: 'testToast.js' //打包後的文件名
  },

4.打包:

npm run build

5.修改package.json:

//"private": true, //刪除這行
//使用時默認尋找的文件
"main": "dist/testToast.js",

6.登錄npm賬號:

npm login

7.發佈插件:

npm publish

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章