Vue 소스 코드 판독 의 Component 구성 요소 등록 실현
구성 요소(Component)는 Vue.js 의 가장 강력 한 기능 중의 하나 이다.구성 요 소 는 HTML 요 소 를 확장 할 수 있 고 재 활용 가능 한 코드 를 패키지 할 수 있 습 니 다.높 은 차원 에서 구성 요 소 는 사용자 정의 요소 이 고 Vue.js 의 컴 파일 러 는 특수 기능 을 추가 합 니 다.어떤 경우 에는 구성 요소 도 is 특성 으로 확 장 된 원생 HTML 요소 로 표현 할 수 있다.
모든 Vue 구성 요 소 는 Vue 의 인 스 턴 스 이기 때문에 같은 옵션 대상(루트 특유 의 옵션 제외)을 받 아들 이 고 같은 수명 주기 갈 고 리 를 제공 할 수 있 습 니 다.
Vue 는 전역 등록 과 부분 등록 두 가지 방식 으로 구성 요 소 를 등록 할 수 있 습 니 다.
전역 등록
등록 방식
전역 등록 은 다음 과 같은 두 가지 등록 방식 이 있 습 니 다.
Vue.coponent 를 통 해 직접 등록 합 니 다.
Vue.component('button-counter', {
//data
data: function () {
return {
count: 0
}
},
template:'#clickBtn'
})
Vue.extend 를 통 해 등록 합 니 다.
var buttonComponent = Vue.extend({
name:'button-counter',
data: function () {
return {
count: 0
}
},
template:'#clickBtn'
});
Vue.component('button-counter', buttonComponent);
구체 적 과정Vue 초기 화 시 initGlobalAPI 는 initAssetRegisters()를 호출 하여 구성 요 소 를 등록 합 니 다.
function initAssetRegisters (Vue) {
//
// ASSET_TYPES Vue ,var ASSET_TYPES = ['component','directive','filter'];
ASSET_TYPES.forEach(function (type) {
Vue[type] = function (
id,
definition
) {
// definition (Function Object),
// definition , options type id
// options , ,
if (!definition) {
return this.options[type + 's'][id]
} else {
/* istanbul ignore if */
if ("development" !== 'production' && type === 'component') {
validateComponentName(id);
}
// component( ) , definition
if (type === 'component' && isPlainObject(definition)) {
definition.name = definition.name || id;
// this.options._base.extend ( Vue.extend ) 。
//Vue.options._base = Vue;
definition = this.options._base.extend(definition);
}
if (type === 'directive' && typeof definition === 'function') {
definition = { bind: definition, update: definition };
}
// this.options[‘component'+ 's'][id]
// , , vue.options 。 init mergeOptions , 。
this.options[type + 's'][id] = definition;
return definition
}
};
});
}
그림 1:initAsset Registers 에서 this.options.base.extend 방법 은 정의 대상 을 구조 기로 바 꾸 고 options.base.extend 는 사실 Vue.extend 입 니 다.다음은 Vue.extend 가 무엇 을 했 는 지 살 펴 보 겠 습 니 다.
Vue.extend = function (extendOptions) {
extendOptions = extendOptions || {};
var Super = this;
var SuperId = Super.cid;
//
var cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {});
// extendOptions
if (cachedCtors[SuperId]) {
return cachedCtors[SuperId]
}
// name , name
var name = extendOptions.name || Super.options.name;
if ("development" !== 'production' && name) {
validateComponentName(name);
}
var Sub = function VueComponent (options) {
this._init(options);
};
// vue Sub.prototype ,Sub vue.prototype 。
// prototype :http://www.cnblogs.com/dolphinX/p/3286177.html
Sub.prototype = Object.create(Super.prototype);
//Sub , https://www.cnblogs.com/SheilaSun/p/4397918.html
Sub.prototype.constructor = Sub;
Sub.cid = cid++;
// vue
Sub.options = mergeOptions(
Super.options,
extendOptions
);
//
Sub['super'] = Super;
// props computed
if (Sub.options.props) {
initProps$1(Sub);
}
if (Sub.options.computed) {
initComputed$1(Sub);
}
// allow further extension/mixin/plugin usage
Sub.extend = Super.extend;
Sub.mixin = Super.mixin;
Sub.use = Super.use;
// vue
ASSET_TYPES.forEach(function (type) {
Sub[type] = Super[type];
});
// enable recursive self-lookup
if (name) {
Sub.options.components[name] = Sub;
}
// keep a reference to the super options at extension time.
// later at instantiation we can check if Super's options have
// been updated.
Sub.superOptions = Super.options;
Sub.extendOptions = extendOptions;
Sub.sealedOptions = extend({}, Sub.options);
// extendOptions
cachedCtors[SuperId] = Sub;
return Sub
};
vue.extend 는 추가 옵션 이 있 는 vue 구조 기 를 되 돌려 주 었 습 니 다.이 구조 기 는 Sub 라 고 명명 되 어 render 를 기다 릴 때 초기 화 됩 니 다.initAsset Registers 가 완 료 된 후 options 에서 전역 구성 요소 button-counter 를 마 운 트 했 습 니 다.그림:
다음은 new Vue()렌 더 링 vue 의 전체 라 이 프 사이클 을 호출 합 니 다.
부분 등록
전역 등록 이 필요 하지 않 거나 구성 요 소 를 다른 구성 요소 에 사용 하지 않 으 면 옵션 대상 의 components 속성 으로 부분 등록 을 할 수 있 습 니 다.
등록 방식
new Vue({
el: '#components-demo',
components:{
'button-counter':{
template:'#clickBtn',
data: function () {
return {
count: 0
}
}
}
}
})
구체 적 과정Vue 부분 구성 요소 등록 도 initAssetRegisters()방법 으로 Vue.extend 를 호출 합 니 다.다른 것 은 createComponent()시 initMixin()에서 판단 합 니 다.
if (options && options._isComponent) {
// Vue , 。
// initInternalComponent , 。
initInternalComponent(vm, options);
}
else {
vm.$options = mergeOptions(
resolveConstructorOptions(vm.constructor),
options || {},
vm
);
}
function initInternalComponent (vm, options) {
var opts = vm.$options = Object.create(vm.constructor.options);
// 。
var parentVnode = options._parentVnode;
opts.parent = options.parent;
opts._parentVnode = parentVnode;
var vnodeComponentOptions = parentVnode.componentOptions;
opts.propsData = vnodeComponentOptions.propsData;
opts._parentListeners = vnodeComponentOptions.listeners;
opts._renderChildren = vnodeComponentOptions.children;
opts._componentTag = vnodeComponentOptions.tag;
if (options.render) {
opts.render = options.render;
opts.staticRenderFns = options.staticRenderFns;
}
}
opts 의 구 조 는 그림 과 같다.부분 등록 은 전역 등록 과 달리 이 유형의 구성 요소 만 부분 적 으로 등 록 된 하위 구성 요소 에 접근 할 수 있 으 며,전역 등록 은 Vue.options 로 확 장 됩 니 다.모든 구성 요 소 를 만 드 는 과정 에서 전역 Vue.options.coponents 에서 현재 구성 요소 의 vm.$options.components 로 확 장 됩 니 다.이것 이 전역 에 등 록 된 구성 요소 가 임의로 사용 할 수 있 는 이유 입 니 다.
구성 요소 이름 정의
구성 요소 이름 을 정의 하 는 방법 은 두 가지 가 있 습 니 다.
짧 은 횡선 형식 을 사용 하 다
Vue.component('button-counter', {})
이 사용자 정의 요 소 를 참조 할 때 <button-counter></button-counter>
을 사용 해 야 합 니 다.낙타 봉 을 사용 하 는 형식.
Vue.component('buttonCounter', { })
이 사용자 정의 요 소 를 참조 할 때 두 가지 이름 을 사용 할 수 있 습 니 다.<buttonCounter>
과 <button-counter>
이 모두 가능 하 다 는 것 이다.DOM(즉 문자열 이 아 닌 템 플 릿)에서 직접 사용 할 때 짧 은 가로줄 만 유효 합 니 다.다음 과 같다.
<div id="components-demo">
<button-counter></button-counter>
</div>
참고 가능:https://www.jb51.net/article/144050.htm이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Vue Render 함수로 DOM 노드 코드 인스턴스 만들기render에서createElement 함수를 사용하여 DOM 노드를 만드는 것은 직관적이지 않지만 일부 독립 구성 요소의 디자인에서 특수한 수요를 충족시킬 수 있습니다.간단한 렌더링 예는 다음과 같습니다. 또한 v...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.