my-link
コンポーネントを使用して、さまざまなアイテムの周りにオンデマンドでアンカータグをラップしています。そのために、カスタムのrender
メソッドが使用されますが、createElement
メソッドはHTMLノードしか作成できないため、プレーンテキストノードを作成することはできないようです。
my-link
コンポーネントの使用法<template v-for="item in items">
<h4>
<my-link :url="item.url">{{ item.text }}</my-link>
</h4>
</template>
my-link
コンポーネントをLink.vue
として実装<script>
export default {
name: 'my-link',
props: { url: String },
render(createElement) {
if (this.url) {
return createElement(
'a', {
attrs: { href: this.url }
}, this.$slots.default
);
}
return createElement(
'span',
this.$slots.default
);
}
};
</script>
<h4>
<a url="/some-link">This item is linked</a>
</h4>
<h4>
<span>Plain text item</span>
</h4>
この特定のシナリオのspan
タグは不要であり、回避することができますが、Vue.jsでこれがどのように、そしてまったく可能かどうかは私にはわかりません。一般的に、カスタムrender
メソッドでプレーンテキストノードを作成する方法を知りたいです。
<h4>
<a url="/some-link">This item is linked</a>
</h4>
<h4>
Plain text item
</h4>
Vue _ vと呼ばれるプロトタイプの内部メソッドを公開します プレーンテキストノードを作成します。プレーンテキスト文字列をレンダリングするために、render関数からこのメソッドを呼び出した結果を返すことができます。
render(h){
return this._v("my string value");
}
この方法でアンダースコアを付けて公開すると、プライベートAPIメソッドとして意図されている可能性が高いため、注意して使用してください。
機能コンポーネントを使用する場合、「これ」も使用できません。この場合、次のようにcontext._v()を呼び出す必要があります。
functional: true,
render(h, context){
return context._v("my string value")
}
これをスロットからテキストを抽出することと組み合わせると(コメントのように、役立つ getChildrenTextContent を使用して)、目的の結果が得られます。
MyLinkコンポーネントの実装を次のように変更することで、上記の回答に記載されている_vメソッドを使用する必要を実際に回避できます(そして、後で名前が変更される可能性のある内部Vueメソッドの使用を回避できる可能性があります)機能コンポーネント。機能コンポーネントはルート要素を必要としないため、非リンク要素の周囲にスパンを配置する必要があります。
MyLinkは次のように定義できます。
const MyLink = {
functional: true,
name: 'my-link',
props: { url: String },
render(createElement, context) {
let { url } = context.props
let slots = context.slots()
if (url) {
return createElement(
'a', {
attrs: { href: url }
}, slots.default
);
}
else {
return slots.default
}
}
};
次に、それを使用するために、別のコンポーネントで次のようなことを行うことができます。
<div>
<h4 v-for="item in items">
<my-link :url="item.url">{{ item.text }}</my-link>
</h4>
</div>
参照: https://codepen.io/hunterae/pen/MZrVEK?editors=101
また、補足として、元のコードスニペットがファイルにLink.vueという名前を付けているようです。 Vueのテンプレートシステムを使用する代わりに独自のレンダリング関数を定義しているため、理論的にはファイルの名前をLink.jsに変更し、開始スクリプトタグと終了スクリプトタグを削除して、完全にJSコンポーネントファイルを作成できます。ただし、コンポーネントにカスタムシステムが含まれている場合(スニペットには含まれていません)、このアプローチは機能しません。お役に立てれば。
コンポーネントのルート要素が必要です。あなたの場合、ルート要素として「h4」を使用できるかもしれません。とにかくv-forループにそれを含めることができるからです。それが済んだら、次のようなテキストノードを作成できます。
return createElement(
'h3',
{},
['Plain text item']
);
Vueのドキュメントによると、createElementの3番目の引数は文字列または配列である可能性があり、文字列の場合はテキストノードに変換されます。
https://vuejs.org/v2/guide/render-function.html#createElement-Arguments