Vue如何使用混合Mixins和插件開發

官網:混合 (mixins) 是一種分發 Vue 組件中可複用功能的很是靈活的方式。混合對象能夠包含任意組件選項。以組件使用混合對象時,全部混合對象的選項將被混入該組件自己的選項。 我的:混入就是用來對vue組件中的公共部分,包括數據對象、鉤子函數、方法等全部選項,進行提取封裝,以達到代碼的複用,混合用處挺大的,然咱們來看看實際用法。javascript

基礎用法

// 這是在main.js根文件中使用,在組中使用也是同樣
import Vue from 'vue';
var mixin = {
    data() {
        return {
            name: 'www.vipbic.com',
            author: '羊先生'
        }
    },
    created: function() {
        console.log('Website:' + this.name)
    },
    methods: {
        foo: function() {
            console.log('做者:' + this.author)
        },
        conflicting: function() {
            console.log('from mixin')
        }
    }
}

new Vue({
    mixins: [mixin],
    render: h => h(App),
    created() {
        let option = this.$options.doNotInit
        console.log('option:', );
        this.foo()
    }
}).$mount('#app')

// 在組建中使用
<template><div></div></template>
<script>
var mixin = {
    data() {
        return {
            name: 'www.vipbic.com',
            author: '羊先生'
        }
    },
    created: function() {
        console.log('Website:' + this.name)
    },
    methods: {
        foo: function() {
            console.log('做者:' + this.author)
        }
    }
}
export default {
    mixins: [mixin],
    created(){
        this.foo()
    }
}
</script>
複製代碼

效果以下,都同樣,能夠看出混合mixins中的created高於組件created執行優先級html

image.png

全局註冊

main.js中直接註冊

import Vue from 'vue';
var mixin = {
    data() {
        return {
            name: 'www.vipbic.com',
            author: '羊先生'
        }
    },
    created: function() {
        console.log('Website:' + this.name)
    },
    methods: {
        foo: function() {
            console.log('做者:' + this.author)
        }
    }
}

Vue.mixin(mixin)
new Vue({
    render: h => h(App)
}).$mount('#app')
複製代碼

效果以下,咱們先不調用,看看控制檯是否有打印結果,能夠發現咱們並未調用,就打印了兩次,按照你們常規考慮可能會想到執行一次,是正常的,即初始化一次,但卻執行了兩次前端

image.png

如何解決執行兩次

我在網上看到都是這麼作的,都說是從官網上看到的,可是我在官網上並無看到,不過的確能解決問題vue

var mixin = {
    data() {
        return {
            name: 'www.vipbic.com',
            author: '羊先生'
        }
    },
    created: function() {
        let option = this.$options.doNotInit;
        console.log(option) // 第一次執行 true 第二次爲 undefined
        if (!option) {
	    // 能夠放置一些你的邏輯,好比一開始就要調用的方法
            console.log('Website:' + this.name)
        }
    },
    methods: {
        foo: function() {
            console.log('做者:' + this.author)
        },
    }
}

Vue.mixin(mixin);
new Vue({
    doNotInit: true, // 添加一個狀態
    render: h => h(App),
}).$mount('#app')
複製代碼

效果以下java

image.png

如何調用

剛上面解釋瞭如何解決調用兩次的問題node

// main.js
import Vue from 'vue';
var mixin = {
    data() {
        return {
            name: 'www.vipbic.com',
            author: '羊先生'
        }
    },
    created: function() {
        let option = this.$options.doNotInit;
        if (!option) {
            console.log('Website:' + this.name)
        }
    },
    methods: {
        foo: function() {
            console.log('做者:' + this.author)
        },
    }
}

Vue.mixin(mixin);
new Vue({
    doNotInit: true,
    render: h => h(App),
}).$mount('#app')

// 在組件中調用
<script>
export default {
    created(){
        this.foo()
    },
}
</script>
複製代碼

image.png

模塊化註冊

新建單獨的mixin.js文件web

import Vue from 'vue';
var mixin = {
    data() {
        return {
            name: 'www.vipbic.com',
            author: '羊先生'
        }
    },
    created: function() {
        let option = this.$options.doNotInit;
        if (!option) {
            console.log('Website:' + this.name)
        }
    },
    methods: {
        foo: function() {
            console.log('做者:' + this.author)
        },
        conflicting: function() {
            console.log('from mixin')
        }
    }
}
export default {
    install(Vue) {
        Vue.mixin(mixin)
    }
}
複製代碼
// 在main.js經過use註冊
Vue.use(myMixin);
new Vue({
    doNotInit: true,
    render: h => h(App),
}).$mount('#app')
複製代碼
// 在組件中調用
<script>
export default {
    created(){
        this.foo()
    },
}
</script>
複製代碼

效果與main.js註冊方式同樣vue-router

image.png

開發插件

上面提到use,也講解一下use相關的知識,並且在開發中也經常看到如Vue.use(VueRouter),Vue.js 在插件開發過程當中須要注意是有一個公開方法 install 。這個方法的第一個參數是 Vue 構造器 , 第二個參數是一個可選的選項對象, 插件一般會爲Vue添加全局功能。插件的範圍沒有限制——通常有下面幾種:vuex

一、添加全局方法或者屬性,如: vue-element]
二、添加全局資源:指令/過濾器/過渡等,如 vue-touch
三、經過全局 mixin方法添加一些組件選項,如: vuex
四、添加 Vue 實例方法,經過把它們添加到 Vue.prototype 上實現。
五、一個庫,提供本身的 API,同時提供上面提到的一個或多個功能,如 vue-router
複製代碼
let MyPlugin = {}
MyPlugin.install = function (Vue, options) {
  // 1. 添加全局方法或屬性
   Vue.prototype.$myMethod = function (options) {
    // 邏輯...
  }

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

  // 3. 注入組件,也就上面提到的混入,vue很是靈活就看你如何去挖掘它
  Vue.mixin({
    created: function () {
      // 邏輯...
    }
  })
}
複製代碼

添加全局方法或屬性

import Vue from 'vue';
//根據install函數規定,第一個傳入Vue的實例,第二個參數是一個可選的選項對象,也就是能夠傳遞參數
MyPlugin.install = function(Vue, options) {
    console.log(options) // 打印參數
    Vue.prototype.myName = options.name
    Vue.prototype.myAuthor = function() {
        return options.author
    }
}
Vue.use(MyPlugin, {
    name: 'www.vipbic.com' // 傳遞參數
    author: '羊先生'
});

new Vue({
    render: h => h(App),
}).$mount('#app')
複製代碼

在組件中調用express

<script>
export default {
    created(){
        console.log(this.myName)
        console.log(this.myAuthor())
    },
}
</script>
複製代碼

效果以下

image.png

添加全局資源

// 經過vue指令的方式添加 指令能夠全局添加還能夠在組件中添加
import Vue from 'vue';
let MyPlugin = {}
MyPlugin.install = function(Vue, options) {
    Vue.directive("hello", {
        bind: function(el, bingind, vnode) {
            console.log(options)
            el.style["color"] = bingind.value;
            console.log("1-bind");
        },
        inserted: function() {
            console.log("2-insert");
        },
        update: function() {
            console.log("3-update");
        },
        componentUpdated: function() {
            console.log('4 - componentUpdated');
        },
        unbind: function() {
            console.log('5 - unbind');
        }
    })
}
// 傳遞參數
Vue.use(MyPlugin, {
    name: 'www.vipbic.com',
    author: '羊先生'
});
new Vue({
    render: h => h(App),
}).$mount('#app')
複製代碼

在組中使用

<template>
    <div>
	<span v-hello="color3">{{message}}</span>
        <button @click="add"> 點擊開始加1</button>
        <button @click="jiebang">解綁</button>
    </div>
</template>
<script>
export default {
    data(){
        return {
            message:10,
            color3:"red"
        }
    },
    methods:{
        add(){
            this.message++;
        },
        jiebang(){
            this.$destroy(); // 解綁 
        }
    },
}
</script>
<style lang="less" scoped>

</style>
複製代碼

頁面效果

image.png

分析結果,在分析結果前,咱們先來看一下Vue.directive的api,來自官網的解釋

el:指令所綁定的元素,能夠用來直接操做DOM
binding:一個對象,包含如下屬性
	name:指令名,不包含v-前綴
	value:指令的綁定值,例如:上面例子中的值就是 red
	oldValue:指令綁定的前一個值,僅在 update 和componentUpdated 鉤子中可用。不管值是否改變均可用
	expression:字符串形式的指令表達式
arg:傳給指令的參數,可選。
modifiers:一個包含修飾符的對象
複製代碼

自定義指令有5個生命週期(也叫做鉤子函數)分別是:

bind, inserted, update, componentUpdate, unbind
複製代碼
// 也就是在對應上面的例子中的
bind 只調用一次,指令第一次綁定到元素時候調用,用這個鉤子能夠定義一個綁定時執行一次的初始化動做。

inserted:被綁定的元素插入父節點的時候調用(父節點存在便可調用,沒必要存在document中)

update: 被綁定與元素所在模板更新時調用,並且不管綁定值是否有變化,經過比較更新先後的綁定值,忽略沒必要要的模板更新

componentUpdate :被綁定的元素所在模板完成一次更新更新週期的時候調用

unbind: 只調用一次,指令月元素解綁的時候調用
複製代碼

圖片黃色框的地方,是在組件使用了v-hello指令後所初始化的數據,而且也打印了接受參數,在點擊解綁後,在點擊開始加1則無效

注入組件

let MyPlugin = {}
MyPlugin.install = function(Vue, options) {
    Vue.mixin({
        data() {
            return {
                name: options.name
            }
        },
        methods: {
            getUser() {
                return options.author
            }
        }
    })
}
Vue.use(MyPlugin, {
    name: 'www.vipbic.com',
    author: '羊先生'
})
new Vue({
    render: h => h(App),
}).$mount('#app')
複製代碼

在組件中使用

export default {
    data(){
        return {
      		
        }
    },
    created(){
 	//這裏name和getUser來自全局注入的
        console.log(this.name)
        console.log(this.getUser())
    }
}
複製代碼

效果

image.png

Vue.use 會自動阻止註冊相同插件屢次,屆時只會註冊一次該插件

參看文章

web前端開發-混合 Vue.directive指令

關於我

相關文章
相關標籤/搜索