javascriptvuejs3relative-pathquasar-frameworkquasar

How to efficiently handle a Vue3/Quasar project with dynamic and static image paths


I have a problem that I would not think is unique. There are times my quasar application I use the vite/quasar shortcut for assets as below:

<q-carousel-slide :name="2" class="column no-wrap flex-center q-pa-none">
  <q-img src="~assets/imgs/carousel/service-upgrade.jpg" style="height:100%">
    <div class="column no-wrap flex-center" style="width: 100%;height:100%">
      <q-img src="~assets/imgs/carousel/logo-white.png" style="max-width:250px" class="q-mb-lg"></q-img>
      <h1 class="text-h1 text-weight-bolder text-white q-my-none">
        ELECTRICAL UPGRADES
      </h1>
      <h4 class="text-h4 text-weight-light q-mt-xs q-mb-lg text-white">
        NEW WIRING & SERVICE UPGRADES
      </h4>
      <q-btn outline color="white" class="q-my-5 my-btn" label="GET A QUOTE" size="lg" @click="layoutStore.toggleContactUsDrawer"/>
    </div>
  </q-img>
</q-carousel-slide>

However, there are also times where its just easier to put these paths in an array to shorten my code with a v-for such as below:

        <q-tab-panel name="lighting">
          <div class="row q-pa-md block-wrapper text-center q-col-gutter-md" style="margin-bottom:100px;">
            <div v-for="item in imagesArray[0]['lighting']" :key="item.id" class="col-sm-4 col-xs-6">
              <q-img loading="eager" :src="getImageUrl(item.link)" class="rounded-borders text-right" :ratio="16/9" @click="openFullScreenImage(getImageUrl(item.link))"/>
            </div>
          </div>
        </q-tab-panel>

Script with relative paths for code above:

  const imagesArray = [{
panels:[
    { id: 1, link: '../assets/imgs/recentwork/panels/panel 1.jpg'},
    { id: 2, link: '../assets/imgs/recentwork/panels/panel 2.jpg'},
    { id: 3, link: '../assets/imgs/recentwork/panels/panel 3.jpg'},
    { id: 4, link: '../assets/imgs/recentwork/panels/panel 4.jpg'},
    { id: 5, link: '../assets/imgs/recentwork/panels/panel 5.jpg'},
    { id: 6, link: '../assets/imgs/recentwork/panels/panel 6.jpg'},
    { id: 7, link: '../assets/imgs/recentwork/panels/panel 7.jpg'},],
lighting: [
    { id: 1, link: '../assets/imgs/recentwork/lighting/lighting 13.jpg'},
    { id: 2, link: '../assets/imgs/recentwork/lighting/lighting 22.jpg'},
    { id: 3, link: '../assets/imgs/recentwork/lighting/lighting 26.jpg'},
    { id: 4, link: '../assets/imgs/recentwork/lighting/lighting 24.jpg'},
    { id: 5, link: '../assets/imgs/recentwork/lighting/lighting 28.jpg'},
    { id: 6, link: '../assets/imgs/recentwork/lighting/lighting 17.jpg'},
    { id: 7, link: '../assets/imgs/recentwork/lighting/lighting 27.jpg'},
    { id: 8, link: '../assets/imgs/recentwork/lighting/lighting 30.jpg'},
    { id: 9, link: '../assets/imgs/recentwork/lighting/lighting 12.jpg'},
],    
commercial: [
    { id: 1, link: '../assets/imgs/recentwork/commercial/commercial 1.jpg'},
    { id: 2, link: '../assets/imgs/recentwork/commercial/commercial 2.jpg'},
    { id: 3, link: '../assets/imgs/recentwork/commercial/commercial 3.jpg'},
    { id: 4, link: '../assets/imgs/recentwork/commercial/commercial 4.jpg'},
    { id: 5, link: '../assets/imgs/recentwork/commercial/commercial 5.jpg'},
    { id: 6, link: '../assets/imgs/recentwork/commercial/commercial 6.jpg'},
    { id: 7, link: '../assets/imgs/recentwork/commercial/commercial 7.jpg'},
    { id: 8, link: '../assets/imgs/recentwork/commercial/commercial 8.jpg'},
    { id: 9, link: '../assets/imgs/recentwork/commercial/commercial 9.jpg'},
],

}]

When I do it this way I find myself having to keep two folders of images. One in the src folder then I also have to maintain an identical folder in the public/assets/imgs folder. So this is a pain to keep recopying over the images but it is even more of a pain if i were to have to maintain both seperately as well.

How can you just use the src assets img folder for everything rather than using this public one which is quite annoying to maintain as well?


Solution

  • non-public assets need to be imported. Using vite, this can be done with new URL(url, import.meta.url). You would just change your array to be along the lines of:

    panels:[
        { id: 1, link: new URL('../assets/imgs/recentwork/panels/panel 1.jpg', import.meta.url).href },
        { id: 2, link: new URL('../assets/imgs/recentwork/panels/panel 2.jpg', import.meta.url).href },
        { id: 3, link: new URL('../assets/imgs/recentwork/panels/panel 3.jpg', import.meta.url).href },
        ...