Member-only story
Vue 3 — Dynamic Components
Building bigger applications requires you to split up your code as best as possible. We need ways to make the code in each component as simple as possible. Luckily for us, options exist.

Let's imagine we have a list of blog posts (I'm using the example from here). In most cases, all posts are most likely so similar that we want to extract one component, let's call it blogPost.vue
, and reuse this. This would be the case if we wanted to show the title, subtitle, and image.
Now let’s imagine that blog posts have different characteristics. Maybe some posts have infographics that need to be interactive instead of their image. Maybe some just need a different design. One way to solve this is to make a lot of if
(conditional) renderings inside the blogPost.vue
component. Another way is to use dynamic components!!
The example
We are going to build on the project started here. It’s a list of blog posts from Medium. Currently, they all have the same design, but we are going to use dynamic components to create three different designs while keeping our components clean.
The base blogPost.vue
component looks like this:
<script setup>
const props = defineProps(['post'])
const openPostWindow = (url) => {
window.open(url, '_blank')
}
</script>
<template>
<div class="card" @click="openPostWindow(post.mediumUrl)">
<div class="card__header">
<img :src="`https://miro.medium.com/v2/resize:fill:500:200/${post.previewImage.id}`" alt="Post Image" class="post-image" />
</div>
<div class="card__body">
<h4>
{{ post.title }}
</h4>
<p>
{{ post.extendedPreviewContent.subtitle }}
</p>
</div>
<div class="card__footer">
<div class="user">
<div class="user__info">
<small>
{{ Math.ceil(post.readingTime) }} minutes
</small>
</div>
</div>
</div>
</div>
</template>
<style scoped>
/* The style can be found in the real repo */
</style>
while the parent looks something like this:
<script setup>
import { usePostsStore } from './../stores/posts'
import MediumPreview from…