四種編寫Vue插件的實際案例

1.使用Vue.extend()+vm.$mount()

Vue.extend()是一個全局API。
用法:
使用基礎Vue構造器,建立一個"子類"。參數是一個包含組件選項的對象。
data選擇是特例,須要注意,在Vue.extend()中它必須是函數。
vue

<div id="mount-point"></div>
複製代碼
// 建立構造器
var Profile = Vue.extend({
    template: '<p>{{firstName}} {{lastName}} aka {{alias}} </p>',
    data: function () {
        return {
            firstName: 'a',
            lastName: 'b',
            alias: 'c'
        }
    }
})
// 建立Profile實例,並掛載到一個元素上。
new Profile().$mount('#mount-point')
複製代碼

結果:node

<p>a b aka c</p>
複製代碼

(1) 實際案例:

用Vue CLI 3初始化一個Vue的項目npm

初始化一個新項目:
vue create vue-plugin-demo

? Please pick a preset:Manually select features
? Check the features needed for your project:
選擇Babel, Router, Vuex
不須要Linter / Formatter
? Use history mode for router? Y
? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.?  In dedicated config files
? Save this as a preset for future project? N

初始化項目以後:

cd vue-plugin-demo
npm run serve
複製代碼

在src/components目錄,新建SayHello.vue組件:bash

SayHello.vue:app

<template>
    <div class="Hello-box" v-show="show">
        <p>Hello</p>
        <h1>{{text}}</h1>
    </div>
</template>
<script>
export default {
    props: {
        show: Boolean,
        text: {
            type: String,
            default: 'success'
        }
    }
}
</script>

<style>
p {
    font-size: 28px;
    text-align: center;
}
h1 {
    text-align: center;
}
</style>
複製代碼

而後,在src/components目錄,新建SayHello.js 插件。ide

SayHello.js:函數

// .js 結尾的是插件
// .vue結尾的是組件
// 插件能夠對組件進行封裝 
import SayHello from './SayHello.vue'
let $vm

export default {
    install (Vue, options) {
        if (!$vm) {
            // Vue.extend()的做用
            const SayHelloPlugin = Vue.extend(SayHello)

            $vm = new SayHelloPlugin({
                el: document.createElement('div')
            })
            document.body.appendChild($vm.$el)
        }
        $vm.show = false 

        let sayhellofn = {
            show(text) {
                $vm.show = true 
                $vm.text = text 
            },
            hide(){
                $vm.show = false
            }
        }

        if (!Vue.$say) {
            Vue.$say = sayhellofn  // 添加全局的方法
        }
    }
}
複製代碼

而後,在App.vue中,使用SayHello.js這個插件。ui

App.vue:this

<template>
  <div id="app">
  
  </div>
</template>

<script>
import SayHello from './components/SayHello.js'
import Vue from 'vue'

// Vue.use()是用來註冊一個全局插件的
// 讓每一個組件,均可以使用這個插件
Vue.use(SayHello)  
export default {
  name: 'App',
  mounted() {
    Vue.$say.show('Friend')
  }
}
</script>
複製代碼

結果:spa

Hello
Friend
複製代碼

總結:

第一種編寫Vue插件的方法:

// 1.添加全局方法或屬性
Vue.$pluginName = function(){
    // 邏輯
}
複製代碼

2.添加全局資源, Vue.directive()

添加全局資源包含了添加全局的指令/過濾器/過渡等,這種方式經過Vue.directive實現。假如咱們有一個focus插件,它獲取某個元素的焦點,則能夠經過如下方式實現:

// 2.添加全局資源
Vue.directive('my-directive', {
    bind(el, binding, vnode, oldVnode) {
        // 邏輯
    }
})
複製代碼

(1) 實際案例:

先用Vue CLI 3初始化一個Vue的項目。

在src/components目錄,新建 focus.js 插件。

focus.js:

// focus.js
export default {
    install(Vue, options) {
        // 添加全局資源,添加全局指令
        Vue.directive('focus', {
            bind: function (){},

            // 當綁定元素插入到DOM中
            inserted: function (el, binding, vnode, oldVnode) {
                // 聚焦元素
                el.focus();
                alert(1);
            },
            update: function (){},
            componentUpdated: function (){},
            unbind: function (){}
        });
    },
}
複製代碼

在App.vue中使用 focus.js 插件:

App.vue:

<template>
    <div id="app">
        <input v-focus>
    </div>
</template>
<script>
import Focus from './components/focus.js'
Vue.use(Focus)
</script>
複製代碼

這樣,在input掛載在DOM中時,便會自動獲取焦點。
Vue.directive()包括5個函數,分別在不一樣的生命週期階段調用。

Vue.directive()包含5個鉤子函數。
一個指令定義對象能夠提供以下幾個鉤子函數(均爲可選):

  • bind:只調用一次,指令第一次綁定到元素時調用。在這裏能夠進行一次性的初始化設置。
  • inserted:被綁定元素插入父節點時調用(僅保證父節點存在,但不必定已被插入文檔中)。
  • update: 所在組件的VNode更新時調用,可是可能發生在其子VNode更新以前。指令的值可能發生了改變,也可能沒有。可是你能夠經過比較更新先後的值來忽略沒必要要的模板更新(詳細的鉤子函數參數見下)。
  • componentUpdated: 指令所在組件的VNode及其子VNode所有更新後調用。
  • unbind: 只調用一次,指令與元素解綁時調用。

若是想註冊局部指令,組件中也接受一個 directives 的選項。
是在組件中,註冊的局部指令。

directives: {
    focus: {
        // 指令的定義
        inserted: function (el) {
            el.focus()
        }
    }
}
複製代碼

而後你能夠在當前組件的模板中任何元素上使用新的 v-focus 屬性,以下:

<input v-focus>
複製代碼

3.注入組件,Vue.mixin()

這一種方式的實現能夠經過調用 Vue.mixin。 混合(mixins) 是一種分發Vue組件中可複用功能的很是靈活的方式。混合對象能夠包含任意組件選項。當組件

// 3.注入組件
Vue.mixin({
    created: function (){
        // 邏輯
    }
})
複製代碼

4.添加實例方法

// 4.添加實例方法
Vue.prototype.$myMethod = function(methodOptions){
    // 邏輯
}
複製代碼
相關文章
相關標籤/搜索