Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linking to images referenced in vuex store in Vue.js

I am using Vue.js for the first time so apologies if this is a basic question – I have set up the vue project with the vue-cli, vue-router and vuex if this information is helpful.

My main issue here is with displaying images or accessing assets. I am able to pull the appropriate data/state in from a data store via a 'getter' and iterate arrays, etc within it (for example, {{student.name}} works perfectly) however when I attempt to display an image with <img :src='student.image'> it fails to load and I get a broken link icon. I've done some research and it seems that there is a webpack naming convention for linking assets with ~/ or ~@/ however neither of these seem to work.

I've seen other examples where people simply link to a fixed asset from the component but because I am iterating the students array I need a more programmatic method. I've seen some examples using computed() properties but I feel like this should be unnecessary?

Below is the code from my component and the relevant parts of my store.js file.

Store.js:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    user: {
      score: 0
    },
    students: [
      {
        id: 1,
        name: 'Advik',
        age: '19',
        studying: 'Physiotherapy',
        image: '~/assets/images/students/advik-1.png'
      },
      {
        id: 2,
        name: 'Jake',
        age: '19',
        studying: 'Drama',
        image: '~/assets/images/students/jake-1.png'
      },
      {
        id: 3,
        name: 'Mel',
        age: '20',
        studying: 'Civil Engineering',
        image: '~/assets/images/students/mel-1.png'
      },
      {
        id: 4,
        name: 'Kaya',
        age: '18',
        studying: 'Law',
        image: '~/assets/images/students/kaya-1.png'
      }
    ]
  },
  mutations: {

  },
  methods: {

  },
  getters: {
    getStudents: state => state.students
  },
  actions: {

  }
})

Intros component:

 <template>
  <div>
    <div class="m-background"></div>
    <Brand />
    <div class="l-container">
      <div v-for="student in getStudents"
           :key="student.id">
           <img :src='student.image'>
           <router-link class="m-btn m-btn--left m-btn__primary"
            :to="{ name: 'home' }">{{ student.name }}
           </router-link>
      </div>
    </div>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
import Brand from '../../components/Brand'

export default {
  components: {
    Brand
  },
  computed: {
    ...mapGetters(['getStudents'])
  },
  name: 'Intros'
}
</script>

<style>

</style>

Thank you so much!

like image 905
Jack Clarke Avatar asked Nov 21 '18 12:11

Jack Clarke


1 Answers

:src='student.image' (v-binding) is executed at runtime, but webpack aliases work in compile time. So you have to wrap the aliased file path in require.

{
  id: 1,
  name: 'Advik',
  age: '19',
  studying: 'Physiotherapy',
  image: require('~@/assets/images/students/advik-1.png')
}
like image 161
Jns Avatar answered Sep 28 '22 21:09

Jns