[英]Is there something like React.Fragment in Vue?
在 React 中我可以做這樣的事情:
// parent component
export default (){
return (
<div>
<div>1</div>
<ChildComponent />
<div>5</div>
</div>
);
}
// child component
export default (){
return (
<React.Fragment>
<div>2</div>
<div>3</div>
<div>4</div>
</React.Fragment>
);
};
// compiled html tags in browser .
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
但是在 Vue 中,當我做同樣的事情時,事情就不同了。
// parent component
<template>
<div>
<div>1</div>
<child-component />
<div>5</div>
</div>
</template>
<script>
import childComponent from 'path/to/childComponent';
export default {
components: { childComponent }
}
</script>
-------------------------------------------------------------
// child component
<template>
<div id='have_to_write_in_vue'>
<div>2</div>
<div>3</div>
<div>4</div>
<div>
</template>
// compiled html tags in browser .
<div>1</div>
<div id='have_to_write_in_vue'>
<div>2</div>
<div>3</div>
<div>4</div>
</div>
<div>5</div>
不同之處在於,'DIV' 標簽在 Vue 中不在同一級別。 我該如何處理?
我問這是因為出現無用的嵌套時出了點問題。
Vue-fragment包為 vue 2 提供了無根組件。
Vue 3 正式支持多根節點組件(片段) https://v3-migration.vuejs.org/new/fragments.html
Vue 中缺少第一方 Fragment 組件讓我抓狂!
我看過vue-fragment
npm 包,但它讓我對他們做了多少感到緊張,並且覺得必須有更好的方法。
我想出了一些非常輕量級的東西......它之所以有效,是因為允許功能組件返回多個根節點。
然而,這不像 Reacts 那樣 100% 有效。 例如,在 React 中,您實際上可以使用React.Fragment
作為應用程序中的根節點。 當您已經在一個組件中時,這似乎僅在 Vue 中有效(即:它不能是您的基本組件的根節點)。
const Fragment = {
functional: true,
render: (h, ctx) => ctx.children
}
使用它...
<Fragment>
<div>Div 1</div>
<div>Div 2</div>
</Fragment>
超級好用...
{someCondition && (
<Fragment>
<div>yay i can use multiple nodes</div>
<div>:)</div>
</Fragment>
)}
<div>
Some inline text {condition ? (
<Fragment>now I can use <strong>html</strong> and {variables}</Fragment>
) : (
<Fragment>So many possibilities</Fragment>
)}
</div>
顯然,Vue.js v3 現在支持開箱即用的片段:片段(Vue.js 文檔)
這是對@Roi 對 Vue v3 的回答的簡單改編。
正如@dakujem 提到的,Vue v3 支持開箱即用的多根組件。
但是它不支持深度嵌套的片段。
更新:您可以嵌套<template>
!
<template>
<div>
<ul>
<li>A</li>
<li>B</li>
<template>
<li>C</li>
<li>D</li>
</template>
</ul>
</div>
</template>
找到了這個很棒的指令,並且經過了實戰考驗! https://github.com/privatenumber/vue-frag
<template>
<div v-frag> <!-- This element will be unwrapped -->
<div v-for="i in 10">
{{ i }}
</div>
</div>
</template>
<script>
import frag from 'vue-frag';
export default {
directives: {
frag
}
};
</script>
從自述文件:
這與 vue-fragment 有什么不同?
它們都旨在做同樣的事情。 但是,vue-fragment 是一個組件,而 vue-frag 是一個指令。 當我看到 vue-fragment 沒有任何測試來確保正確的行為,有很多無人看管的問題,並且似乎沒有積極維護時,我做了 vue-frag。 就大小而言,它們都很小,但 vue-frag 略小(993B vs 798B)。
對於使用 Vue 3 + JSX/TSX 的用戶,您可以執行以下任一操作:
<>
<p>one</p>
<p>two</p>
</>
或者
import { Fragment } from 'vue';
<Fragment>
<p>one</p>
<p>two</p>
</Fragment>
注意:我使用@vue/babel-plugin-jsx
來支持 JSX/TSX。
TLDR:創建一個組件Frag.vue
:
<template>
<slot></slot>
</template>
正如其他答案中提到的,您可以嵌套template
s,但需要注意:
你可以做v-if
<template>
<ul>
<li>
first
</li>
<template v-if="true">
<li>
second
</li>
<li>
third
</li>
</template>
<li>
fourth
</li>
</ul>
</template>
生產:
<ul>
<li>first</li>
<li>second</li>
<li>third</li>
<li>fourth</li>
</ul>
或v-for
<template>
<ul>
<li>
first
</li>
<template v-for="i in list">
<li>
second {{i}}
</li>
<li>
third {{i}}
</li>
</template>
<li>
fourth
</li>
</ul>
</template>
生產:
<ul>
<li>first</li>
<li>second 0</li>
<li>third 0</li>
<li>second 1</li>
<li>third 1</li>
<li>fourth</li>
</ul>
但是,如果沒有v-for
或v-if
:
<template>
<ul>
<li>
first
</li>
<template>
<li>
second
</li>
<li>
third
</li>
</template>
<li>
fourth
</li>
</ul>
</template>
它產生
<ul>
<li>first</li>
<li>fourth</li>
</ul>
您可以通過始終使用v-if="true
來解決它,但它不太理想。
話雖如此,因為模板中的插槽將所有傳遞的子項分散到默認插槽中,您可以創建一個非常簡單的組件:
<template>
<slot></slot>
</template>
而已。 將其命名為Frag.vue
,在需要的地方導入它。 您可以將它與v-if
、 v-for
一起使用,也可以兩者都不使用。
<template>
<ul>
<li>
first
</li>
<Frag v-if="true">
<li>
second (v-if)
</li>
<li>
third (v-if)
</li>
</Frag>
<Frag v-for="i in list">
<li>
second {{i}} (v-for)
</li>
<li>
third {{i}} (v-for)
</li>
</Frag>
<Frag>
<li>
second (nothing)
</li>
<li>
third (nothing)
</li>
</Frag>
<li>
fourth
</li>
</ul>
</template>
生產:
<ul>
<li>
first
</li>
<li>
second (v-if)
</li>
<li>
third (v-if)
</li>
<li>
second 0 (v-for)
</li>
<li>
third 0 (v-for)
</li>
<li>
second 1 (v-for)
</li>
<li>
third 1 (v-for)
</li>
<li>
second (nothing)
</li>
<li>
third (nothing)
</li>
<li>
fourth
</li>
</ul>
只需使用嵌套template
標簽來包裝多個子 Vue 組件。
<template>
<template>
<div class="my-first-child"></div>
<div class="my-second-child"></div>
<div class="my-third-child"></div>
</template>
</template>
這將導致
<div class="my-first-child"></div>
<div class="my-second-child"></div>
<div class="my-third-child"></div>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.