1. 程式人生 > 其它 >vue 一個元件內多個彈窗_一個 Vue 模板可以有多個根節點(Fragments)?

vue 一個元件內多個彈窗_一個 Vue 模板可以有多個根節點(Fragments)?

技術標籤:vue 一個元件內多個彈窗

如果我們試圖建立一個沒有根節點的Vue模板,比如這樣:

<template>
<div>Node1div>
<div>Node2div>
template>

我們就會收到編譯或執行時錯誤,因為模板必須具有單個根元素。

通常,我們通過在最外層包裹一層 div 來解決這個問題,但這個div元素一般沒有啥使用,就是讓模板符合單根需求。

<template>
<div>
<div>Node1div>
<div>Node2div>
div>
template>

這樣的方式通常問題不在,但是在某些情況下,擁有多根模板是必要的。在本文中,我們來探討一下何時需要以及如何解決多根的問題。

渲染陣列

某些情況下,可能需要元件渲染子節點陣列以包含在父元件中。

例如,一些CSS特性需要非常特殊的元素層次結構才能正確工作,比如CSS gridflex,不能在父元素和子元素之間使用包裝器。

<template>
<divstyle="display:flex">

<FlexChildren/>
div>
template>

還有一個問題,在元件中新增包裝元素可能會導致渲染無效的HTML。例如,如果要構建table,則錶行必須僅具有用於子項的表單元格

<template>
<table>
<tr>

<TableCells/>
tr>
table>
template>

簡而言之,單根需求意味著在Vue中將無法返回子元素的元件的設計模式。

Fragments

這個單根限制對於React也是一個問題,但是它在版本16中提供了一個稱為[fragments][1]的功能。要使用它,只需要將多根模板包裝在特殊的React.Fragment元素中:

classColumnsextendsReact.Component{
render(){
return(
<React.Fragment><td>Hellotd><td>Worldtd>React.Fragment>
);
}
}

這將使子元件沒有多餘包裝,還有一個簡潔的短語法<>

classColumnsextendsReact.Component{
render(){
return(
<><td>Hellotd><td>Worldtd>>
);
}
}

Vue中的 Fragments

那麼 Vue 是否也會引入 fragments?這可能不會很快,原因是虛擬DOM差異演算法依賴於具有單個根的元件。根據Vue貢獻者Linus Borg的說法:

“允許 fragments 需要對[diffing]演算法進行重大更改…不僅要使其能夠正常工作,而且還必須使其具有高效能。…這是一項非常繁重的任務”

具有渲染功能的函式元件

函式元件沒有單根限制,因為它們不需要像有狀態元件那樣在虛擬DOM中進行區分。這意味著,如果元件只需要返回靜態HTML,那麼擁有多個根節點也沒什麼問題。

還有一個警告:我們需要使用渲染功能,因為vue-loader當前不支援多根功能([儘管對此進行了討論][2])。

exportdefault{
functional:true,
render:h=>[
h('tr',[
h('td','foo'),
h('td','bar'),
]),
h('tr',[
h('td','lorem'),
h('td','ipsum'),
])
];
});

-------------------------------------------

importTableRowsfrom"TableRows";

newVue({
el:'#app',
template:`
"app"> `,
components:{
TableRows
}
});

使用指令技巧

還可以使用一種簡單的方法來繞過單根限制。就是使用自定義指令,首先我們先所包裹的元素刪除

之前的:







中間步驟:






最終:

<parent>

<child/>
<child/>
parent>

要使它正常工作有點棘手,這裡可以使用由Julien Barbay寫的 [vue-fragments][3] 的外掛。

vue-fragments

vue-fragments可以作為一個外掛安裝到你的Vue專案中

import{Plugin}from"vue-fragments";
Vue.use(Plugin);

該外掛註冊了一個全域性VFragment元件,將其用作元件模板中的包裝器,類似於React片段的語法:

<template>
<v-fragment>
<div>Fragment1div>
<div>Fragment2div>
v-fragment>
template>

我不確定這個外掛在所有的用例中有多健壯——它看起來可能是脆弱的——但在我做的實驗中,它工作得很好。

作者:Anthony Gore 譯者:前端小智 來源:vuejsdevelopers
https://vuejsdevelopers.com/2018/09/11/vue-multiple-root-fragments/

交流

1b69766a8e9897700189ccc954fd01f8.png

2020年 16 個最有用的 Vue UI庫

記好這 24 個 ES6 方法,用來解決實際開發的 JS 問題

[小智第五次視訊]Vue 的選擇器元件(這種思路我們要掌握)

使用Vue 自定義檔案選擇器元件(基礎雖簡單,但思路我們要掌握)

Vue 中的 Props 與 Data 細微差別,你知道嗎?