vue.js提供的各種API的內部實現原理
阿新 • • 發佈:2021-10-14
全域性API和例項方法不同,後者是在Vue的原型上掛載方法,也就是在Vue.prototype上掛載方法,而前者是直接在Vue上掛載方法。示例:
vue.extend = function(extendOption) {
...
}
Vue.extend
引數:Vue.extend({})
用法:使用基礎Vue構造器建立一個"子類",引數是包含元件選項的物件
data選項是特例,在Vue.extend中,它必須是函式,完整程式碼:
let cid = 1 Vue.extend = function (extendOptions) { extendOptions = extendOptions || {} const Super = this const SuperId = Super.cid const cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {}) if(cachedCtors[SuperId]) { return cachedCtors[SuperId] } const name = extendOptions.name || Super.options.name if(process.env.NODE_ENV !== 'production') { if(!/^[a-zA-Z][\w-]*$/.test(name)) { warn( 'invalid component name:"' + name + '". Component name' + 'can only contain alphaumeric characters and the hyphen, ' + 'and must start with a letter.' ) } } const Sub = function VueComponent(options) { this._init(options) } Sub.prototype = Object.create(Super.prototype) Sub.prototype.constructor = Sub Sub.cid = cid++ Sub.options = mergeOptions( Super.options, extendOptions ) Sub['super'] = Super if(Sub.options.props) { initProps(Sub) } if(Sub.options.computed) { initComputed(Sub) } Sub.extend = Super.extend Sub.mixin = Super.mixin Sub.use = Super.use ASSET_TYPES.forEach(function(type) { Sub[type] = Super[type] }) if(name) { Sub.options.components[name] = Sub } Sub.superOptions = Super.options Sub.extendOptions = extendOptions Sub.sealedOptions = extend({}, Sub.options) //快取建構函式 cachedCtors[SuperId] = Sub return Sub }
Vue.directive(id, [definition])
引數:{String} id,{function | Object} [definition]
用法:註冊或獲取全域性指令。
//註冊 Vue.directive('my-directive', { bind: function() {}, inserted: function() {}, update: function() {}, componentUpdated: function() {}, unbind: function() {} }) //註冊(指令函式) Vue.directive('my-directive', function() { //這裡將會被bind和updata呼叫 }) //getter方法,返回已註冊的指令 let myDirective = Vue.directive('my-directive')
Vue.directive方法的作用是註冊或獲取全域性指令,而不是讓指令生效。
註冊指令程式碼實現:
//用於儲存指令的位置 Vue.options = Object.create(null) Vue.options['directives'] = Object.create(null) Vue.directive = function (id, definition) { if(!definition) { //直接返回之前儲存好了的 return this.options['directives'][id] } else { if(typeof definition === 'function') { //預設監聽並給definition重新賦值 definition = { bind: definition, update: definition} } } //儲存到options中 this.options['directives'][id] = definition return definition }
首先在Vue建構函式上建立了options熟悉來存放選項,並在選項上新增directive方法。
這個方法接收兩個引數,它可以用來註冊和獲取指令,當definition為空的時候,根據id直接返回指令。當definition存在時,說明是註冊指令,檢查definition的型別,如果為函式的話就將bind,undate兩個函式預設監聽,並用這個物件去覆蓋definition,然後在options中儲存,最後返回definition;如果不是函式說明是使用者自定義的指令,直接儲存在options上不進行操作。
Vue.filter(id, [definition])
引數:{string} id,{Function | Object} [definition]
用法:註冊或獲取全域性過濾器。
//註冊
Vue.filter('my-filter', value => {
//返回處理後的值
})
// getter的方法,返回已註冊的過濾器
let myFilter = Vue.filter('my-filter')
過濾器可以用在兩個地方:雙花括號插值和v-bind表示式:
//在雙花括號裡
{{ message | my-filter}}
//在v-bind中
<div v-bind:id = 'rawId | my-filter'></div>
與Vue.directive類似,Vue.filter的作用僅僅是註冊或獲取全域性過濾器。它們倆的註冊過程也很類似,將過濾器儲存在Vue.options['filters']中即可。程式碼實現:
Vue.options['filters'] = Object.create(null)
Vue.filter = function (id, definition) {
if(!definition) {
//直接返回之前儲存的
return this.options['filters'][id]
} else {
//註冊過濾器
this.options['filters'][id] = definition
return definition
}
}