vue 一個元件內多個彈窗_一個 Vue 模板可以有多個根節點(Fragments)?
技術標籤:vue 一個元件內多個彈窗
如果我們試圖建立一個沒有根節點的Vue模板,比如這樣:
<template>
<div>Node1div>
<div>Node2div>
template>
我們就會收到編譯或執行時錯誤,因為模板必須具有單個根元素。
通常,我們通過在最外層包裹一層 div
來解決這個問題,但這個div
元素一般沒有啥使用,就是讓模板符合單根需求。
<template>
<div>
<div>Node1div>
<div>Node2div>
div>
template>
這樣的方式通常問題不在,但是在某些情況下,擁有多根模板是必要的。在本文中,我們來探討一下何時需要以及如何解決多根的問題。
渲染陣列
某些情況下,可能需要元件渲染子節點陣列以包含在父元件中。
例如,一些CSS特性需要非常特殊的元素層次結構才能正確工作,比如CSS grid
或flex
,不能在父元素和子元素之間使用包裝器。
<template>
<divstyle="display:flex">
<FlexChildren/>
div>
template>
還有一個問題,在元件中新增包裝元素可能會導致渲染無效的HTML。例如,如果要構建table,則錶行必須僅具有用於子項的表單元格
。
<template>
<table>
<tr>
<TableCells/>
tr>
table>
template>
簡而言之,單根需求意味著在Vue中將無法返回子元素的元件的設計模式。
Fragments
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
那麼 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-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/
交流
交流
2020年 16 個最有用的 Vue UI庫
記好這 24 個 ES6 方法,用來解決實際開發的 JS 問題
[小智第五次視訊]Vue 的選擇器元件(這種思路我們要掌握)
使用Vue 自定義檔案選擇器元件(基礎雖簡單,但思路我們要掌握)
Vue 中的 Props 與 Data 細微差別,你知道嗎?