2017-11-24 4 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> 

私の質問は:どのように私は彼らの特定のクラス(すなわち、「パネル・ヘッダー」と子どもコンポーネント(パネル・ヘッダー&パネル-フッター)「を含める」ことができますクラスとそれ以外はの両方をそのまま使用すると、(パネル本体とクラス)のパネルボディの作成に自由度があります。

別の言い方をすると、次のようになります。子を制御することはできますが、コンポーネントを分割してパネルの中央に[子供]を配置するにはどうすればよいですか?ベストに関して

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

EDIT:

私のレンダリングの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:文脈 - それは正確に何か、そしてそれが子供たちにアクセスする独特の特徴をもっと知る場所と; 2:componentOptionsと同じです - このような機能を使用するこの素晴らしい方法について、ウェブにはほとんど情報がありません!どこでもっと入手できますか? 最高、Paco –

+1

@PacoPaciciコンテキストはこちら[こちら](https://vuejs.org/v2/guide/render-function.html#Functional-Components)に記載されています。これは、 'function'コンポーネントのレンダリング関数を記述しているときにのみ機能します。 'componentOptions'に関しては、ドキュメンテーションは技術的には[ここ](https://vuejs.org/v2/api/#VNode-Interface)ですが、あまり役に立ちません。私は主に経験から学んだ。 componentOptionsを使用すると、コンポーネントに独自の静的プロパティを作成し、代わりにそのプロパティのvnodeを調べることができます。 – Bert

+0

これはいくつかの強力なvue-tricksです!私はすぐにそれに飛び込む必要があります。なぜなら、私は "レンダリングでエラーが発生しています:未定義のプロパティ 'children'を読み込めません。あなたがそれを提案したのとは違って、PanelHeaderとPanelFooterをレンダリング関数の外側で定義しようとしています - 別々の[dot] jsコンポーネントです。 Panelのレンダリングでこれらのbadboysを捕まえることはまだ可能ですか?乾杯。 –

関連する問題