[Vuejs]-How to load a component twice but both with different text in Vue 3

4๐Ÿ‘

โœ…

You are right to think about speed, but the question should also be on the principle of not repeating your code unnecessarily. So, even if creating two components would not influence the speed, it would not be the best option, since there is a way to do the same thing with a single component.

The solution is to use the slot.

ChildComponent:

<template>
  <div>
     <slot name="contentText"></slot>
     <img src="your/path"/>
  </div>
</template>

ParentComponent

<template>
    <div>
       <ChildComponent>
           <template #contentText>
              <p>Lorem ipsum 1</p>
           </template>
       </ChildComponent>

       <ChildComponent>
           <template #contentText>
              <p>Lorem ipsum 2</p>
           </template>
       </ChildComponent>
    </div>
</template>

You could have used props, however, you would lose flexibility and lock your component into an ultra-precise pattern, preventing its reuse in multiple cases. Indeed, the main difference between props and slot is that props can only pass data to the child without any control over how it will be rendered. With slots, on the other hand, the parent can determine exactly how the data should be rendered, or even pass another component.

Thus, with the use of slot you can make your component more flexible and reusable in the future

๐Ÿ‘คfchancel

0๐Ÿ‘

Do you guys have advice and/or know on what way I should pass the text ? โ€“ Basically it depends how you are going to use this component. If you are planning to reuse this component in several places in your application, In that scenario the approach you are following is correct so that you can just pass text and image URL dynamically in that component and it will work fine.

<text-image :heading="headingText" :description="descriptionText" :image="imageURL"></text-image>

Live Demo :

const app = Vue.createApp({
  data() {
    return {
      taxtImageData: [{
        headingText: "Heading A",
        descriptionText: "Description A",
        imageURL: "Image URL A"
      }, {
        headingText: "Heading B",
        descriptionText: "Description B",
        imageURL: "Image URL B"
      }]
    };
  },
})

app.component('text-image', {
  template: `
    <div style="border: 1px solid black; padding: 5px; margin: 5px">
        <h3>{{ heading }}</h3>
      <p>{{ description }}</p>
    <div>`,
  props: {
    heading: {
      type: String,
      default: ''
    },
    description: {
      type: String,
      default: ''
    },
    image: {
      type: String,
      default: ''
    }
  }
}) 
app.mount('#demo')
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<div id="demo">
  <text-image
      v-for="(data, index) in taxtImageData"
      :key="index"
      :heading="data.headingText"
      :description="data.descriptionText"
      :image="data.imageURL">
  </text-image>
</div>
๐Ÿ‘คDebug Diva

Leave a comment