2017-11-24 5 views
4

JS 렌더링 함수를 사용하여 Vue.js - just a bootstrap panel with optional heading, content and optional footer에서 일견 쉬운 구성 요소를 만드는 데 어려움을 겪고 있습니다. 그것은 이런 식으로 뭔가를 이동하는 아이디어는 다음과 같습니다Vue의 렌더링 함수 내에서 자식 제어

<panel> 

    <panel-header> Header </panel-header> 

    [ The panel content goes here ] 

    <panel-footer> Footer </panel-footer> 

</panel> 

내 질문은 : 나는 그들의 특정 클래스 (예 : "패널 헤더"어린이의 구성 요소 (패널 헤더 & 패널 바닥 글) "포함"어떻게 클래스)를 둘 다 선택적으로 유지하십시오. 은 패널 본체의 구성을 자유롭게 허용합니다. 은 고유 한 클래스 (예 : "panel-body"클래스 및 props.title)을 사용합니까?

다르게 표현하려면 어떻게해야합니까? 어린이를 제어 할 수 있지만 구성 요소를 분리하고 패널 가운데에 [하위]를 채우려면 어떻게해야합니까? 베스트 감사와

import classNames from 'classnames'; 

export const props = { 
tag: { 
    type: String, 
    default: "div" 
}, 
className: { 
    type: String 
}, 
align: { 
    type: String, 
    default: 'left' 
}, 
title: { 
    type: String, 
}, 
header: { 
    type: String, 
} 
}; 

export default { 
functional: true, 
props, 
render(h, { props, data, children }) { 
    const dataObj = { 
    class: classNames(
     'card', 
     props.align ? 'text-' + props.align : '', 
     props.className ? props.className : '' 
    ), 
}; 
const title = [ 
    h('h4', { 
    class: 'card-title' 
    }, props.title) 
]; 

const content = [ 
    h('div', { 
    class: 'card-body' 
    }) 
]; 
return h(props.tag, dataObj, [title, children]); 
} 
}; 

, 파코 Pacici

편집 :

내 렌더링의 sctipt은 다음과 같이 보이는 내가 위에서 그것을 한 번, 내가 원하는 효과를 얻을 수 있습니다 것을 알고있다 - 패널에 머리글, 내용 및 바닥 글이 올바른 순서로 표시됩니다. 그러나 바닥 글과 머리글을 제외하고 패널의 콘텐츠에만 일부 속성을 추가하고 싶다면 어떻게해야합니까? 따라서, 그들은 아이들로 간주 될 것이고 그러므로 나의 조작에 복종 할 것입니다. 저는 그것들을 별개로 다루고 싶습니다만, 아주 똑같은 기능 안에서요.

답변

1

본질적으로, 자녀들을 검사하고 필요에 따라 머리글과 바닥 글을 움켜 잡고 원하는대로 레이아웃하십시오.

console.clear() 
 

 
const PanelHeader = { 
 
    template: `<div>Im a panel header</div>` 
 
} 
 

 
const PanelFooter = { 
 
    template: `<div>Im a panel Footer</div>` 
 
} 
 

 
const Panel = { 
 
    functional: true, 
 
    render(h, context){ 
 
    // find the header if there is one. Note that if there is more than 
 
    // one panel-header, only the first one will be used 
 
    let header = context.children.find(c => c.componentOptions && c.componentOptions.tag === "panel-header") 
 
    // same deal for the footer 
 
    let footer = context.children.find(c => c.componentOptions && c.componentOptions.tag === "panel-footer") 
 
    // filter out anything that isn't header/footer 
 
    let body = context.children.filter(c => c !== header && c !== footer) 
 
    
 
    // layout as desired. 
 
    return h('div', [header, body, footer]) 
 
    } 
 
} 
 

 
new Vue({ 
 
    el: "#app", 
 
    components: {Panel, PanelHeader, PanelFooter} 
 
})
<script src="https://unpkg.com/[email protected]"></script> 
 
<div id="app"> 
 
    <panel> 
 
    <panel-footer></panel-footer> 
 
    some stuff 
 
    <panel-header></panel-header> 
 
    </panel> 
 
    <hr> 
 
    <panel> 
 
    some stuff 
 
    </panel> 
 
    <hr> 
 
    <panel> 
 
    <panel-footer></panel-footer> 
 
    some stuff 
 
    </panel> 
 
</div>

이 예

만 구성 요소를 얻을 그들을 배치하는 방법을 보여줍니다. 분명히 당신의 예제를 정확히 따르지 않거나 필요한 클래스를 포함하지 않습니다.

+0

당신, 선생님, 내 마음을 뜨다.1 : Context - 정확하게 무엇이며, 그것에 대해 더 자세히 알 수있는 곳은 자녀 액세스의 고유 한 기능입니다. 2 : componentOptions의 경우와 동일합니다. 웹에서이 기능을 사용하는 멋진 방법에 대한 정보는 거의 없습니다. 더 얻을 수있는 곳은 어디입니까? 최고, Paco –

+1

@PacoPacici 컨텍스트는 [여기] (https://vuejs.org/v2/guide/render-function.html#Functional-Components)에 설명되어 있습니다. '함수'컴포넌트에 대한 렌더링 함수를 작성할 때만 효과가 있습니다. 'componentOptions'에 관해서는, 문서는 기술적으로 [여기] (https://vuejs.org/v2/api/#VNode-Interface)이지만별로 도움이되지 않습니다. 나는 경험에 대해 주로 배웠다. 구성 요소에 자신의 정적 속성을 만들고 대신 해당 속성의 vnode를 검사하여 componentOptions를 사용할 수 있습니다. – Bert

+0

이것들은 강력한 vue-tricks입니다! 지금 당장은 "렌더링 오류 : 정의되지 않은 속성 '자식을 읽을 수 없습니다. 당신이 제안한 것과 다르게 PanelHeader와 PanelFooter를 렌더링 함수 외부에서 정의하려고합니다. 분리 된 [도트] js 구성 요소입니다. Panel의 렌더링에서 이러한 badboys를 잡는 것이 아직 가능합니까? 건배 –