Discussion
Discussion copied to clipboard
Better content insertion API
Context: https://hacks.mozilla.org/2015/06/the-state-of-web-components/ (See the "Distribution" section)
TL;DR: browser vendors cannot agree on the content distribution API for web components. The current <content select="xxx">
syntax will likely be replaced.
The post describes two possible new APIs: an imperative one and a new declarative one. In Vue this has to do with the internal compilation cycle so we are mostly interested in the new declarative API, the "name slots" proposal from Apple:
Component template:
<slot name="header"></slot>
<slot></slot>
<slot name="footer"></slot>
<div>some shadow content</div>
When using the component:
<x-page>
<header slot="header">header</header>
<footer slot="footer">footer</footer>
<h1>my page title</h1>
<p>my page content<p>
</x-page>
Rendered result:
<x-page>
<header slot="header">header</header>
<h1>my page title</h1>
<p>my page content<p>
<footer slot="footer">footer</footer>
<div>some shadow content</div>
</x-page>
The benefits of this proposal over the current <content>
API, is that it is much more explicit (the exposed "slots" essentially become part of the component's interface), and thus makes it easier to compose nested components:
<list-item>
<avatar slot="left-avatar" src="{{user.avatarUrl}}"></avatar>
<p slot="primary-text">{{user.name}}</p>
<p slot="secondary-text">{{user.tagline}}</p>
</list-item>
I'm hoping to ship this in 1.0 - and it's even possible to maintain compat with the current <content>
syntax. Discuss!
This is great, love how explicit it is the communication between the content definition and the actual data
I don't really have any opinion on this, but when it comes to content insertion, I really like the principle React uses, which is to write all the html to the shadow dom, and on each update to the dom, they just insert/remove the diff between the previous and the last html (which leads to great speed). Having said that, Vue.js is still 100 times better than React, and I suppose implementing something like that is mostly a design/architecture decision that would go pretty deep into the core of the library.
Explicit is better than implicit.
And I can not come up with the use case where <content>
fits better then named slots.
I don't get why the footer slot changes position from component to rendered results. Apart from that: :+1: for the new syntax. I didn't really like the strange css nth-child selection method at all.
@Nirazul all content without explicit slot name gets distributed into the unnamed default <slot>
.
Ah great, thank you, makes sense to me. Looking forward to the change :)
What would happen if a slot was blank?
<x-page>
<header slot="header">header</header>
<h1>my page title</h1>
<p>my page content<p>
</x-page>
Would the output then miss the heading?
<x-page>
<h1>my page title</h1>
<p>my page content<p>
<footer slot="footer">footer</footer>
<div>some shadow content</div>
</x-page>
It would be nice to be able to access the child component context from slot.
<child>
<ul>
<li class="header">Header</li>
<li class="collection-item" v-for="item in items">
<slot name="my-item">{{ item }}</slot>
</li>
</ul>
</child>
<parent>
<child>
<p slot="my-item">{{ item.id }} {{ item.name }}</p>
</child>
</parent>
Expected Result:
<ul>
<li class="header">Header</li>
<li class="collection-item" v-for="item in items">
<p slot="my-item">ID NAME</p>
</li>
</ul>