Content Distribution
https://goo.gl/ttW89y
#vuelondon / Blake Newman / @blakenewman
What is content distribution?
Interweave the parent “content” and the component’s own template
Default List Component
Custom list componet
List component
<template>
<ul>
<li v-for="item in data">{{ item }}</li>
</ul>
</template>
<script>
export default {
props: {
data: Array,
},
};
</script>
<style>
// Custom Styles
</style>
Implementation
<template>
<list :data="[...]" />
</template>
<script>
import List from '@component/list';
export default {
components: {
List,
},
};
</script>
Output
List component with image
<template>
<ul>
<li v-for="item in data">
{{ item }}
<img v-if="item === 'A User'"
:src="require('@asset/logo.png')"
alt="A User Image"
width="10px"
height="10px" />
</li>
</ul>
</template>
<script>
export default {
props: {
data: Array,
},
};
</script>
Implementation
<template>
<list :data="[...]" />
</template>
<script>
import List from '@component/list';
export default {
components: {
List,
},
};
</script>
Output
Meh :/
Slots
<!-- AppLayout.vue -->
<template>
<div class="container">
<header>
<slot name="header" />
</header>
<main>
<slot />
</main>
<footer>
<slot name="footer" />
</footer>
</div>
</template>
<!-- Parent implementing AppLayout.vue -->
<app-layout>
<h1 slot="header">Here might be a page title</h1>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<p slot="footer">Here's some contact info</p>
</app-layout>
Slots - output
<div class="container">
<header>
<h1>Here might be a page title</h1>
</header>
<main>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
</main>
<footer>
<p>Here's some contact info</p>
</footer>
</div>
List component with slot
<template>
<ul>
<li v-for="item in data">
{{ item }}
<slot />
</li>
</ul>
</template>
<script>
export default {
props: {
data: Array,
},
};
</script>
Implementation
<template>
<list :data="[...]">
<img v-if="item === 'A User'"
:src="require('@asset/logo.png')"
alt="A User Image"
width="10px"
height="10px" />
</list>
</template>
<script>
import List from '@component/list';
export default {
components: {
List,
},
};
</script>
Output
Meh :/
List component with scoped slot
(Version 2.1+)
<template>
<ul>
<slot name="item"
v-for="item in data"
:text="item">
{{ item }} <!-- Fallback Content -->
</slot>
</ul>
</template>
<script>
export default {
props: {
data: Array,
},
};
</script>
Implementation
<template>
<list :data="[...]">
<template scope="child" v-if="child.text === 'A User'">
{{ child.text }}
<img :src="require('@asset/logo.png')"
alt="A User Image"
width="10px"
height="10px" />
</template>
</list>
</template>
<script>
import List from '@component/list';
export default {
components: {
List,
},
};
</script>
Output
Yay :)
VueConf 2017
conf.vuejs.org
Wrocław, Poland - 2017
The official Vue.js Conference
Content Distribution (Vue.js)
By Blake Newman
Content Distribution (Vue.js)
Best practices for content distribution with slots within Vue.js Applications. London Vue.js Meetup #4 (Lightning Talk)
- 2,168