Reputation: 173
I'm playing with Vue.js and trying to display a local image from a json file unsuccessfully.
Stories.vue
<template>
<div class="container col-md-5">
<div class="Library-title">
<div class="app-name">Stories List</div>
</div>
<story-tyle v-for="story in stories" v-bind:story="story" :key="story.id"></story-tyle>
</div>
</template>
<script>
import StoryTyle from '@/components/StoryTyle.vue'
import storyData from '@/assets/data/StoriesData.json'
export default {
name: 'Stories',
components: {
StoryTyle
},
data () {
return {
stories: storyData
}
}
}
</script>
StoryTile.vue
<template>
<div class="story-wrapper col-6">
<div class="story-cover">
<div class="story-cover-img" v-bind:style="{ 'background-image': 'url(' + story.cover + ')' }" v-bind:alt="story.title">
<a v-on:click="nextPath()">
<div class="story-details cover-select">
<span v-if="story.frequency" class="story-frequency resize">{{ story.frequency }}</span>
<div class="story-title resize">{{ story.title }}</div>
<div class="story-author resize">{{ story.author }}</div>
</div>
</a>
</div>
</div>
</div>
</template>
<script>
export default {
import: require('../assets/js/resize.js'),
props: ['story'],
name: 'story-tyle',
methods: {
nextPath () {
if (this.story.frequency) {
this.$router.push({name: 'Episodes'})
} else {
this.$router.push({name: 'Read'})
}
}
}
}
</script>
StoriesData.json
[
{
"id": 1,
"title": "Example of story title",
"author": "Author Name",
"cover": "../assets/img/covers/Blue-border-cover.png",
"frequency": "weekly"
},
{
...
}
]
The other data display correctly, but not the cover image. I've looked for different solutions but nothing seems to work. Images loads correctly if I get the data directly in the script of Stories.vue like this:
data () {
return {
stories: [
{
...
cover: require('../assets/img/covers/Blue-border-cover.png')
},
And this is the relevant folder structure:
src
├─ assets
│ ├─ data
│ │ └─ StoriesData.json
│ └─ img
│ └─ covers
│ └─ Blue-border-cover.png
├─ components
│ └─ EpisodeTyle.vue
└─ views
└─ Episodes.vue
what am I doing wrong?
Upvotes: 2
Views: 8071
Reputation: 173
After the input received in here, I played around with different solution and found a very simple solution that worked.
The problem is that images need to use require. So in StoryTile.vue I replaced:
v-bind:style="{ 'background-image': 'url(' + story.cover + ')' }"
with:
v-bind:style="{ 'background-image': 'url(' + require('../assets/img/covers/' + story.cover) + ')' }"
also in the json file, "cover": "Blue-border-cover.png" and not the entire path which is now expresses in StoryTile.vue.
and this did the trick!
Upvotes: 1
Reputation: 4464
Try to do it this way:
const images = require.context('@/assets/img/covers', false, /\.png$|\.jpg$/)
export default {
...
methods: {
loadImg(imgPath) {
return images('./' + imgPath)
},
...
}
}
In your template:
<div class="story-cover-img"
:style="`background-image: url(${loadImg(story.cover)})`"
:alt="story.title"></div>
In .json
[
{
"id": 1,
"title": "Example of story title",
"author": "Author Name",
"cover": "Blue-border-cover.png", // only name of a file
"frequency": "weekly"
},
{
...
}
]
Let me know if it worked.
Another idea:
.json
[
{
"id": 1,
"title": "Example of story title",
"author": "Author Name",
"cover": "url(\'/assets/img/covers/Blue-border-cover.png\')", // set bg url here
"frequency": "weekly"
},
{
...
}
]
And then in your template:
<div class="story-cover-img"
:style="`background-image: ${story.cover}`"
:alt="story.title"></div>
Let me know if that worked 😃
Upvotes: 1