混合 (mixins) 是一種分發 Vue 組件中可複用功能的很是靈活的方式。混合對象能夠包含任意組件選項。以組件使用混合對象時,全部混合對象的選項將被混入該組件自己的選項。javascript
Vue.extend()用以建立沒有掛載的的子類,可使用該子累建立多個實例
[javascript] view plain copy var Profile = Vue.extend({ template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>', data: function () { return { firstName: 'Walter', lastName: 'White', alias: 'Heisenberg' } } }) // 建立 Profile 實例,並掛載到一個元素上。 new Profile().$mount('#mount-point')
mixins 將兩個的對象的混合爲一個數組,彼此均可以被調用,下面爲演示代碼及其結果 當對象鍵值對 鍵名衝突時,保留非mixin對象的鍵值對
<div id="app"></div> <script> var myMixin={ template:'<h1>holle mixin</h1>', methods:{ hello:function(){ console.log('this is mixin') }, say:function(){ console.log('I am mixin') } } }; var Component=Vue.extend({ mixins:[myMixin], methods:{ lsit:function(){ console.log('I am lsit') }, say:function(){ console.log('I am mixin say') } } }); var newcom=new Component().$mount('#app') newcom.hello(); newcom.lsit(); newcom.say(); </script>
也能夠全局註冊混合對象。 注意使用! 一旦使用全局混合對象,將會影響到 全部 以後建立的 Vue 實例。使用恰當時,能夠爲自定義對象注入處理邏輯。html
// 爲自定義的選項 'myOption' 注入一個處理器。 Vue.mixin({ created: function () { var myOption = this.$options.myOption if (myOption) { console.log(myOption) } } }) new Vue({ myOption: 'hello!' }) // => "hello!"
謹慎使用全局混合對象,由於會影響到每一個單首創建的 Vue 實例(包括第三方模板)。大多數狀況下,只應當應用於自定義選項,就像上面示例同樣。 也能夠將其用做 Plugins 以免產生重複應用vue
Vue.js 容許你註冊自定義指令,實質上是讓你教 Vue 一些新技巧:怎樣將數據的變化映射到 DOM 的行爲。你可使用Vue.directive(id, definition)的方法傳入指令id和定義對象來註冊一個全局自定義指令。定義對象須要提供一些鉤子函數(所有可選):java
bind: 僅調用一次,當指令第一次綁定元素的時候。node
update: 第一次是緊跟在 bind 以後調用,得到的參數是綁定的初始值;之後每當綁定的值發生變化就會被調用,得到新值與舊值兩個參數。webpack
unbind:僅調用一次,當指令解綁元素的時候。web
例子:vue-router
Vue.directive('my-directive', { bind: function () { // 作綁定的準備工做 // 好比添加事件監聽器,或是其餘只須要執行一次的複雜操做 }, update: function (newValue, oldValue) { // 根據得到的新值執行對應的更新 // 對於初始值也會被調用一次 }, unbind: function () { // 作清理工做 // 好比移除在 bind() 中添加的事件監聽器 } })
一旦註冊好自定義指令,你就能夠在 Vue.js 模板中像這樣來使用它(須要添加 Vue.js 的指令前綴,默認爲 v-):
<div v-my-directive="someValue"></div>
若是你只須要 update 函數,你能夠只傳入一個函數,而不用傳定義對象:
Vue.directive('my-directive', function (value) { // 這個函數會被做爲 update() 函數使用 })
全部的鉤子函數會被複制到實際的指令對象中,而這個指令對象將會是全部鉤子函數的this
上下文環境。指令對象上暴露了一些有用的公開屬性:express
el: 指令綁定的元素數組
vm: 擁有該指令的上下文 ViewModel
expression: 指令的表達式,不包括參數和過濾器
arg: 指令的參數
raw: 未被解析的原始表達式
name: 不帶前綴的指令名
這些屬性是隻讀的,不要修改它們。你也能夠給指令對象附加自定義的屬性,可是注意不要覆蓋已有的內部屬性。
* bind: 只調用一次,指令第一次綁定到元素時調用,用這個鉤子函數能夠定義一個在綁定時執行一次的初始化動做。 * inserted: 被綁定元素插入父節點時調用(父節點存在便可調用,沒必要存在於 document 中)。 * update: 所在組件的 VNode 更新時調用,可是可能發生在其孩子的 VNode 更新以前。指令的值可能發生了改變也可能沒有。可是你能夠經過比較更新先後的值來忽略沒必要要的模板更新 (詳細的鉤子函數參數見下)。 * componentUpdated: 所在組件的 VNode 及其孩子的 VNode 所有更新時調用。 * unbind: 只調用一次, 指令與元素解綁時調用。 * 接下來咱們來看一下鉤子函數的參數 (包括 el,binding,vnode,oldVnode) 。
*el: 指令所綁定的元素,能夠用來直接操做 DOM 。 * binding: 一個對象,包含如下屬性: * name: 指令名,不包括 v- 前綴。 * value: 指令的綁定值, 例如: v-my-directive="1 + 1", value 的值是 2。 * oldValue: 指令綁定的前一個值,僅在 update 和 componentUpdated 鉤子中可用。不管值是否改變均可用。 * expression: 綁定值的字符串形式。 例如 v-my-directive="1 + 1" , expression 的值是 "1 + 1"。 * arg: 傳給指令的參數。例如 v-my-directive:foo, arg 的值是 "foo"。 * modifiers: 一個包含修飾符的對象。 例如: v-my-directive.foo.bar, 修飾符對象 modifiers 的值是 { foo: true, bar: true }。 * vnode: Vue 編譯生成的虛擬節點,查閱 VNode API 瞭解更多詳情。 * oldVnode: 上一個虛擬節點,僅在 update 和 componentUpdated 鉤子中可用。
除了 el 以外,其它參數都應該是隻讀的,儘可能不要修改他們。若是須要在鉤子之間共享數據,建議經過元素的 dataset 來進行。
同一個特性內部,逗號分隔的多個從句將被綁定爲多個指令實例。在下面的例子中,指令會被建立和調用兩次:
<div v-demo="color: 'white', text: 'hello!'"></div>
若是想要用單個指令實例處理多個參數,能夠利用字面量對象做爲表達式:
<div v-demo="{color: 'white', text: 'hello!'}"></div> Vue.directive('demo', function (value) { console.log(value) // Object {color: 'white', text: 'hello!'} })
若是在建立自定義指令的時候傳入 isLiteral: true ,那麼特性值就會被當作直接字符串,並被賦值給該指令的 expression。字面指令不會試圖創建數據監視。
<div v-literal-dir="foo"></div>
Vue.directive('literal-dir', { isLiteral: true, bind: function () { console.log(this.expression) // 'foo' } })
然而,在字面指令含有 Mustache 標籤的情形下,指令的行爲以下:
指令實例會有一個屬性,this._isDynamicLiteral被設爲true; 若是沒有提供update函數,Mustache 表達式只會被求值一次,並將該值賦給this.expression。不會對錶達式進行數據監視。 若是提供了update函數,指令將會爲表達式創建一個數據監視,而且在計算結果變化的時候調用update。
若是你的指令想向 Vue 實例寫回數據,你須要傳入 twoWay: true 。該選項容許在指令中使用
this.set(value)。
Vue.directive('example', { twoWay: true, bind: function () { this.handler = function () { // 把數據寫回 vm // 若是指令這樣綁定 v-example="a.b.c", // 這裏將會給 `vm.a.b.c` 賦值 this.set(this.el.value) }.bind(this) this.el.addEventListener('input', this.handler) }, unbind: function () { this.el.removeEventListener('input', this.handler) } })
傳入 acceptStatement: true 可讓自定義指令像 v-on 同樣接受內聯語句:
<div v-my-directive="a++"></div>
Vue.directive('my-directive', { acceptStatement: true, update: function (fn) { // the passed in value is a function which when called, // will execute the "a++" statement in the owner vm's // scope. } })
可是請明智地使用此功能,由於一般咱們但願避免在模板中產生反作用。
有時候,咱們可能想要咱們的指令能夠以自定義元素的形式被使用,而不是做爲一個特性。這與 Angular 的 E 類指令的概念很是類似。元素指令能夠看作是一個輕量的自定義組件(後面會講到)。你能夠像下面這樣註冊一個自定義的元素指令:
Vue.elementDirective('my-directive', { // 和普通指令的 API 一致 bind: function () { // 對 this.el 進行操做... } })
使用時咱們再也不用這樣的寫法:
<div v-my-directive></div>
而是寫成:
<my-directive></my-directive>
元素指令不能接受參數或表達式,可是它能夠讀取元素的特性,來決定它的行爲。與一般的指令有個很大的不一樣,元素指令是終結性的,這意味着,一旦 Vue 遇到一個元素指令,它將跳過對該元素和其子元素的編譯 - 即只有該元素指令自己能夠操做該元素及其子元素。
插件一般會爲Vue添加全局功能。插件的範圍沒有限制——通常有下面幾種:
添加全局方法或者屬性,如: vue-custom-element
添加全局資源:指令/過濾器/過渡等,如 vue-touch
經過全局 mixin 方法添加一些組件選項,如: vue-router
添加 Vue 實例方法,經過把它們添加到 Vue.prototype 上實現。
一個庫,提供本身的 API,同時提供上面提到的一個或多個功能,如 vue-router
Vue.js 的插件應當有一個公開方法 install 。這個方法的第一個參數是 Vue 構造器 , 第二個參數是一個可選的選項對象:
MyPlugin.install = function (Vue, options) { // 1. 添加全局方法或屬性 Vue.myGlobalMethod = function () { // 邏輯... } // 2. 添加全局資源 Vue.directive('my-directive', { bind (el, binding, vnode, oldVnode) { // 邏輯... } ... }) // 3. 注入組件 Vue.mixin({ created: function () { // 邏輯... } ... }) // 4. 添加實例方法 Vue.prototype.$myMethod = function (methodOptions) { // 邏輯... } }
經過全局方法 Vue.use() 使用插件:
// 調用 `MyPlugin.install(Vue)` Vue.use(MyPlugin)
也能夠傳入一個選項對象:
Vue.use(MyPlugin, { someOption: true })
Vue.use 會自動阻止註冊相同插件屢次,屆時只會註冊一次該插件。
Vue.js 官方提供的一些插件 (例如 vue-router) 在檢測到 Vue 是可訪問的全局變量時會自動調用 Vue.use()。
然而在例如 CommonJS 的模塊環境中,你應該始終顯式地調用 Vue.use():
// 用 Browserify 或 webpack 提供的 CommonJS 模塊環境時 var Vue = require('vue') var VueRouter = require('vue-router') // 不要忘了調用此方法 Vue.use(VueRouter)
文章來自 : 搜狗搜到你 我的網站 :huai.ye2012vip@qq.com