Vue 슬롯 실현 원리
<!-- comA -->
<template>
<div class='demo'>
<slot><slot>
<slot name='test'></slot>
<slot name='scopedSlots' test='demo'></slot>
</div>
</template>
<!-- -->
<comA>
<span> </span>
<template slot='test'> </template>
<template slot='scopedSlots' slot-scope='scope'> ( ){{scope.test}}</template>
<template v-slot:scopedSlots='scopeProps' slot-scope='scope'> ( ){{scopeProps.test}}</template>
</comA>
2.현상 을 통 해 본질 을 본다.슬롯 의 역할 은 내용 의 분 배 를 실현 하고 내용 의 분 배 를 실현 하 는 것 이 며 두 가지 조건 이 필요 하 다.
slot
탭 은 자리 표시 자,부모 구성 요소 에 있 는 슬롯 내용 으로 이해 할 수 있 습 니 다.바로 배포 할 내용 입 니 다.슬롯 처리 의 본질은 지 정 된 내용 을 지 정 된 위치 에 두 는 것 이다.쓸데없는 말 은 많이 하지 않 고 이 글 에서 알 수 있 을 것 이다.render
방법 중 플러그 를 어떻게 사용 합 니까 vue
구성 요소 의 예화 순 서 는 부모 구성 요소 상태 초기 화(data
,computed
,watch
..)->템 플 릿 컴 파일->생 성 render
방법->예화 렌 더 링 watcher
->render
방법 을 호출 하여 VNode
->patch VNode
을 생 성 합 니 다.실제 DOM
으로 변환->인 스 턴 스 화 서브 구성 요소-->...같은 절 차 를 반복 합 니 다->하위 구성 요소 가 생 성 한 진실 DOM
을 부모 구성 요소 가 생 성 한 진실 DOM
에 마 운 트 하고 페이지 에 마 운 트 합 니 다->이전 노드 제거상기 절차 에서 추측 할 수 있다.
1.부모 구성 요소 템 플 릿 은 하위 구성 요소 이전에 해석 되 기 때문에 부모 구성 요 소 는 먼저 슬롯 템 플 릿 내용 을 가 져 옵 니 다.
2.하위 구성 요소 템 플 릿 을 분석 한 후에 하위 구성 요소 가
render
방법 으로 VNode
을 생 성 할 때 일부 수단 을 통 해 슬롯 의 VNode
노드 를 얻 을 수 있 습 니 다.3.역할 영역 슬롯 은 하위 구성 요소 내 변 수 를 가 져 올 수 있 기 때문에 역할 영역 슬롯 의
VNode
생 성 은 동적 입 니 다.즉,실시 간 으로 하위 구성 요소 에 들 어 가 는 역할 영역 scope
이 필요 합 니 다.전체 슬롯 의 처리 단 계 는 크게 세 단계 로 나 뉜 다.
<div id='app'>
<test>
<template slot="hello">
123
</template>
</test>
</div>
<script>
new Vue({
el: '#app',
components: {
test: {
template: '<h1>' +
'<slot name="hello"></slot>' +
'</h1>'
}
}
})
</script>
4.부모 구성 요소 컴 파일 단계컴 파일 은 템 플 릿 파일 을
AST
문법 트 리 로 해석 하고 슬롯 template
을 다음 과 같은 데이터 구조 로 해석 합 니 다.
{
tag: 'test',
scopedSlots: { //
// slotName: ASTNode,
// ...
}
children: [
{
tag: 'template',
// ...
parent: parentASTNode,
children: [ childASTNode ], // , 123
slotScope: undefined, //
slotTarget: "\"hello\"", //
slotTargetDynamic: false //
// ...
}
]
}
5.부모 구성 요소 생 성 렌 더 링 방법AST
문법 트 리 에 따라 렌 더 링 방법 문자열 을 분석 한 결과 부모 구성 요소 가 생 성 된 결 과 는 다음 과 같다.이 구 조 는 우리 가 직접 쓴 render
방법 과 일치 하고 본질 은 모두 VNode
을 생 성 하 는 것 이 며 _c
또는 h
은 this.$createElement
의 줄 임 말 에 불과 하 다.
with(this){
return _c('div',{attrs:{"id":"app"}},
[_c('test',
[
_c('template',{slot:"hello"},[_v("
123
")])],2)
],
1)
}
6.부모 구성 요소 생 성 VNoderender
방법 을 호출 하여 VNode
을 생 성 하고 VNode
의 구체 적 인 형식 은 다음 과 같다.
{
tag: 'div',
parent: undefined,
data: { // VNode
attrs: { id: '#app' }
},
context: componentContext, //
elm: undefined, // DOM
children: [
{
tag: 'vue-component-1-test',
children: undefined, // ,
parent: undefined,
componentOptions: { //
Ctor: VueComponentCtor, //
data: {
hook: {
init: fn, //
insert: fn,
prepatch: fn,
destroy: fn
},
scopedSlots: { // , VNode
slotName: slotFn
}
},
children: [ //
tag: 'template',
propsData: undefined, // props
listeners: undefined,
data: {
slot: 'hello'
},
children: [ VNode ],
parent: undefined,
context: componentContext //
// ...
]
}
}
],
// ...
}
vue
에서 구성 요 소 는 페이지 구조의 기본 단원 이다.상기 VNode
에서 알 수 있 듯 이 VNode
페이지 의 등급 구 조 는 test
구성 요소 에서 끝나 고 test
구성 요소 children
처 리 는 하위 구성 요소 초기 화 과정 에서 처 리 될 것 이다.하위 구성 요소 구조 방법 조립 과 속성 을 vue-dev\src\\core\vdom\\create-component.js createComponent
방법 에 통합 합 니 다.구성 요소 의 정례 화 호출 입 구 는 vue-dev\src\\core\vdom\patch.js createComponent
방법 에 있 습 니 다.7.하위 구성 요소 상태 초기 화
인 스 턴 스 화 서브 구성 요 소 는
initRender
->resolveSlots
방법 에서 하위 구성 요소 슬롯 노드 를 구성 요소 역할 영역 vm
에 마 운 트 하고 마 운 트 형식 은 vm.$slots = {slotName: [VNode]}
형식 입 니 다.8.하위 구성 요소 컴 파일 단계
하위 구성 요 소 는 컴 파일 단계 에서
slot
노드 를 다음 과 같은 AST
구조 로 컴 파일 합 니 다.
{
tag: 'h1',
parent: undefined,
children: [
{
tag: 'slot',
slotName: "\"hello\"",
// ...
}
],
// ...
}
9.하위 구성 요소 생 성 렌 더 링 방법생 성 된 렌 더 링 방법 은 다음 과 같다.그 중에서
_t
은 renderSlot
방법의 약자 로 renderSlot
방법 에서 우 리 는 슬롯 내용 과 슬롯 점 을 직관 적 으로 연결 할 수 있다.
//
with(this){
return _c('h1',[ _t("hello") ], 2)
}
// :vue-dev\src\core\instance\render-helpers\render-slot.js
export function renderSlot (
name: string,
fallback: ?Array<VNode>,
props: ?Object,
bindObject: ?Object
): ?Array<VNode> {
const scopedSlotFn = this.$scopedSlots[name]
let nodes
if (scopedSlotFn) { // scoped slot
props = props || {}
if (bindObject) {
if (process.env.NODE_ENV !== 'production' && !isObject(bindObject)) {
warn(
'slot v-bind without argument expects an Object',
this
)
}
props = extend(extend({}, bindObject), props)
}
// , VNode
nodes = scopedSlotFn(props) || fallback
} else {
// VNode
nodes = this.$slots[name] || fallback
}
const target = props && props.slot
if (target) {
return this.$createElement('template', { slot: target }, nodes)
} else {
return nodes
}
}
역할 영역 슬롯 과 구명 슬롯 의 차이
<!-- demo -->
<div id='app'>
<test>
<template slot="hello" slot-scope='scope'>
{{scope.hello}}
</template>
</test>
</div>
<script>
var vm = new Vue({
el: '#app',
components: {
test: {
data () {
return {
hello: '123'
}
},
template: '<h1>' +
'<slot name="hello" :hello="hello"></slot>' +
'</h1>'
}
}
})
</script>
역할 도 메 인 슬롯 은 일반 슬롯 에 비해 슬롯 내용 이 하위 구성 요소 역할 도 메 인 변 수 를 얻 을 수 있다 는 차이 가 있 습 니 다.하위 구성 요소 변 수 를 주입 해 야 하기 때문에 구명 슬롯 에 비해 역할 영역 슬롯 은 다음 과 같은 몇 가지 차이 가 있 습 니 다.역할 도 메 인 슬롯 은 렌 더 링 방법 을 조립 할 때 주입 역할 도 메 인 을 포함 하 는 방법 을 생 성 합 니 다.
createElement
에 비해 VNode
을 생 성 하고 주입 역할 도 메 인 방법 패키지 가 한 층 더 생 성 되 었 습 니 다.이 는 슬롯 VNode
역할 도 메 인 슬롯 은 하위 구성 요소 가 VNode
을 생 성 할 때 생 성 되 며,서명 슬롯 은 부모 구성 요소 가 VNode
을 만 들 때 생 성 됩 니 다._u
은 resolveScopedSlots
으로 노드 설정 항목 을 {scopedSlots: {slotName: fn}}
형식 으로 전환 하 는 역할 을 한다.
with (this) {
return _c('div', {
attrs: {
"id": "app"
}
}, [_c('test', {
scopedSlots: _u([{
key: "hello",
fn: function(scope) {
return [_v("
" + _s(scope.hello) + "
")]
}
}])
})], 1)
}
하위 구성 요소 가 초기 화 될 때 서명 슬롯 노드 를 처리 하고 구성 요소 $slots
에 마 운 트 합 니 다.역할 영역 슬롯 은 renderSlot
에서 직접 호출 됩 니 다.그 밖 에 다른 절 차 는 대체로 같다.슬롯 역할 체 제 는 이해 하기 어렵 지 않 습 니 다.관건 은 템 플 릿 분석 과 render 함수 생 성 이라는 두 단계 의 내용 이 비교적 많 고 절차 가 길 며 이해 하기 어렵 습 니 다.
10.사용 기교
이상 의 분석 을 통 해 슬롯 처리 절 차 를 대충 알 수 있 습 니 다.작업 중 대부분 은 템 플 릿 으로
vue
코드 를 작성 하지만 어떤 때 는 템 플 릿 에 한계 가 있 기 때문에 render
방법 을 통 해 vue
의 구성 요소 추상 능력 을 확대 해 야 합 니 다.그러면 render
방법 에서 우리 의 슬롯 사용 방법 은 다음 과 같다.10.1.서명 슬롯
슬롯 처 리 는 일반적으로 두 조각 으로 나 뉜 다.
slot
이름 VNode
을 직접 가 져 오기 때문에 하위 구성 요 소 는 slot
탭 을 부모 구성 요소 로 대체 하여 생 성 된 VNode
으로 만 들 수 있 습 니 다.하위 구성 요 소 는 초기 화 상태 에서 구성 요소 $slots
속성 에 서명 슬롯 을 마 운 트 합 니 다.
<div id='app'>
<!-- <test>-->
<!-- <template slot="hello">-->
<!-- 123-->
<!-- </template>-->
<!-- </test>-->
</div>
<script>
new Vue({
// el: '#app',
render (createElement) {
return createElement('test', [
createElement('h3', {
slot: 'hello',
domProps: {
innerText: '123'
}
})
])
},
components: {
test: {
render(createElement) {
return createElement('h1', [ this.$slots.hello ]);
}
// template: '<h1>' +
// '<slot name="hello"></slot>' +
// '</h1>'
}
}
}).$mount('#app')
</script>
10.2 역할 영역 슬롯역할 영역 슬롯 의 사용 이 비교적 유연 하여 하위 구성 요소 상 태 를 주입 할 수 있 습 니 다.역할 영역 슬롯+
render
방법 은 2 차 구성 요소 의 패 키 징 에 매우 큰 역할 을 합 니 다.밤 을 들 어 ElementUI
table
구성 요 소 를 JSON
데이터 로 포장 할 때 역할 영역 슬롯 의 용도 가 매우 크다.
<div id='app'>
<!-- <test>-->
<!-- <span slot="hello" slot-scope='scope'>-->
<!-- {{scope.hello}}-->
<!-- </span>-->
<!-- </test>-->
</div>
<script>
new Vue({
// el: '#app',
render (createElement) {
return createElement('test', {
scopedSlots:{
hello: scope => { // ,
return createElement('span', {
domProps: {
innerText: scope.hello
}
})
}
}
})
},
components: {
test: {
data () {
return {
hello: '123'
}
},
render (createElement) {
// function, VNode
let slotVnode = this.$scopedSlots.hello({ hello: this.hello })
return createElement('h1', [ slotVnode ])
}
// template: '<h1>' +
// '<slot name="hello" :hello="hello"></slot>' +
// '</h1>'
}
}
}).$mount('#app')
</script>
이상 은 Vue 슬롯 실현 원리 에 대한 상세 한 내용 입 니 다.Vue 슬롯 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 해 주 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 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에 따라 라이센스가 부여됩니다.