Vue: unexpected token: ':' in image path - vue.js

I'm passing an image path to a child Vue component but get:
unexpected token: ':' in https://path.to.image/image.jpg
I've created a Vue sandbox that illustrates the problem.
HTML
<div class="js-product-map">
<product-map
:logo="https://path.to.image/image.jpg"
/>
</div>
Component
<template>
<div>
<img :src="image" />
</div>
</template>
<script>
export default {
props: {
logo: {
type: String,
required: true,
},
},
computed: {
image() {
return this.logo;
},
},
};
</script>
What am I doing wrong?

Can you clarify what it is you're trying to do exactly? Because it's not entirely clear to me.
The error you're getting is coming from this:
<div class="js-product-map">
<product-map
:logo="https://path.to.image/image.jpg"
/>
</div>
It's complaining about the : on the logo attribute. But I question why you're doing it this way to begin with. Typically you only want a single selector in index.html as the root of your app. Unless you're trying to have multiple Vue instances.
The way that you have your ProductMap component set up in your sandbox seems like it would accomplish what you're trying to do in index.html.

Related

img src is not working within v-for loop when using list items in vue js [duplicate]

I got a parent component which sends a data object to the children component like this:
<child object-data=" url: 'url here', title: 'Title'"></child>
Then on my children component, I get this object data by doing:
<script>
export default {
props: [
'objectData'
]
}
</script>
Now, for some reason, I can use title without any problem like this {{ objectData.title }} and shows up.
But when it comes to the URL inside an img tag it's not rendering the image.
I attempted doing the following:
<img :src="objectData.url"/> <--- not rendering
<img v-bind:src="objectData.url"/> <--- not rendering
<img v-bind:src="require(objectData.url)"/> <-- throws a warning error because it's not a path but an object I guess.
<img v-bind:src="{objectData.url}"/> <--- throws an error
<img v-bind:src="{{objectData.url}}"/> <--- throws an error
When I check on the dom element, it doesn't even contain a src attribute afterwards.
If I write down the URL without an object, it works.
<img v-bind:src="src/assets/images/icon.png"/>
But I want my URL to come from a parent component.
Any ideas on how to solve this? I added the url-loader on my webpack file:
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader'
}
I also attempted returning objectData.url from a computed/methods fuction:
computed: {
getImageUrl: function() {
return objectData.url;
}
}
And then use it like :src=“getImageUrl” or :src=“{{getImageUrl}}” and I wasn’t lucky either.
I faced the same issue and i fixed it by using require function :
in the parent component App.vue :
<carousel-posts :posts="posts" />
export default {
name: "app",
data() {
return {
posts: [
{
img: require("./assets/logo.png"),
title: "Title 1",
subTitle: "Sub Title 1",
body:"lorem ipsum ..."
}
...
]
};
}
...
}
in the child component i loop through the posts and bind the image src as follows :
<div class="card-body" v-for="(post,idx) in posts" >
<img class="card-img" :src="post.img" />
...
</div>
<script>
export default {
props: ["posts"],
...
So in your case you should have something like :
<child :object-data="objectData"></child>
...
data(){
return{
dataObject:{
url: require('./assets/someimg.png'),
title: 'Title'
}
}
}
Update :
my project tree :
src
|_assets
| |_logo.png
|_components
| |_CarouselPosts.vue
|_App.vue
Two alternatives:
Static links that vue resolves. But they're src-based and don't work with webpack / file-loader:
<img :src="'../assets/filename.png'"/>
Works with webpack. Note the ".default" at the end:
<img :src="require('../assets/filename.png').default"/>
Documentation relevant effective Nov 2019:
https://github.com/vuejs/vue-loader/issues/1612

passing object to component using v-for

I am trying to send a series of objects that are in an array to a child component using v-for, but when I try to access them from the child component, it tells me that the props are not defined.
Im using Quasar Framework actually
This is how I pass the data:
<div class="row justify-center">
<foo
v-for="brand in brands"
:key="brand.id"
:brand="brand"
></foo>
</div>
<script>
import foo from "src/components/foo.vue";
export default {
components: {
foo
},
data() {
return {
brands: []
};
},
methods: {
async getData() {
let x = await get.getData();
this.brands = x.data;
console.log(this.brands);
}
},
mounted() {
this.getData();
}
};
</script>
brands is an array that obtains two objects from a request made to a local database, which I have already verified that it receives the data correctly
And this is the component file and how I try to get the properties:
<q-card class="my-card" flat bordered>
<q-img
:src="require(`../assets/${brand.img}`)"
:alt="brand.img + ' Logo'"
/>
<div class="text-h5 q-mt-sm q-mb-xs">{{ brand.name }}</div>
<div class="text-caption text-grey">
<p>
{{ brand.price }}
</p>
</div>
<script>
export default {
name: "foo",
props: ["brand"],
data() {
return {
expanded: false
};
},
};
</script>
but when I try to execute the code it gives me the following error:
Error in render: "Error: Cannot find module './undefined'
I know one way to make it work, and it is by creating a property for each of the object's values, for example:
<component
v-for="brand in brands"
:key="brand.id"
:name="brand.name"
:price="brand.price"
></component>
But I dont think thats the correct way to do this....
try to change
import component from "src/components/component.vue";
to
import foo from "src/components/component.vue";
on your components section you just call foo instead of foo:component
I am not sure, but:
Looks like ${brand} is empty. Your function GetData() is async, so the <foo> is created before the GetData() has its data set/returned.
You can change
<foo v-for="brand in brands" :key="brand.id" :brand="brand"></foo>
To
<foo v-if="brands.length> 0" v-for="brand in brands" :key="brand.id" :brand="brand"></foo>
To make sure that the element is renderd after the data if set.
Note: v-if is when the html is rendered, v-show is just a css display hide, but the html is always renderd

Vue: can't use a component inside another compontent

I am trying to use a child compontent in another compontent and it does not work. I have been trying to solve this problem looking for typos etc. for hours, but can't find anything.
Menu.vue
<template>
<div class='navbar-and-alert'>
<alert/>
<nav class='navbar'>
</nav>
</div>
</template>
<script>
import Alert from './Alert.vue'
export default {
name: 'Navbar',
compontents: {
Alert
},
data (){
return {
}
},
}
</script>
Alert.vue
<template>
<section class='alert-section'>
<p class='alert-section__content'>
...
</p>
<a href=''><img src='/static/assets/img/close.svg' class='alert-section__close-icon'></a>
</section>
</template>
<script>
export default {
name: 'Alert',
}
</script>
I get this alert in console:
Vue warn]: Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option.
found in
The alert component works when used inside App.vue
components has a typo:
compontents: {
Alert
},
Should be:
components: {
Alert
},

Nuxt clientside only component

I have a global component for rendering thumbnail collections. This global component uses Glightbox library to open / view the images. However it does not work serverside because it checks the browser / navigator. But wonder how I can disable / exclude the use of glightbox when rendering serverside ?
Here is my component :
<template>
<div v-if="items.length > 0" class="gallery">
<div v-for="(item, myindex) in items" :key="myindex" class="thumbcontainer">
<a :href="item.source.version_900x900.url" :class="setLightBoxClass()">
<div
v-lazy:background-image="item.source.version_250x250.url"
class="innerthumb"
style="--aspect-ratio:1.33"
/>
</a>
</div>
</div>
</template>
<script>
import GLightbox from 'glightbox'
export default {
name: 'BaseGallery',
inheritAttrs: false,
props: {
items: Array,
galleryId: Number
},
data() {
return {
lightbox: undefined
}
},
mounted() {
this.$nextTick(function() {
this.initLightBoxes()
})
},
methods: {
setLightBoxClass() {
return {
glightbox: true,
['glightbox-' + this.galleryId]: true,
thumblink: true
}
},
initLightBoxes() {
this.lightbox = GLightbox({ selector: 'glightbox-' + this.galleryId })
}
}
}
</script>
The "import" statement triggers the error of "Navigator undefined". Any suggestion how to solve this ? Is there a clean way to to make a serverside and clientside version of the same component ?
I use it in other components like this :
<base-gallery :items="items" :gallery-id="123" />
I tried adding client-only, but that does not fix it.
I've also put the loading of the component in in plugin like this :
Vue.component(componentName, componentConfig.default || componentConfig)
And then in my nuxt config :
plugins: [
{ src: '~/plugins/baseGallery', mode: 'client' }
],
But that doesn't work eighter :
The client-side rendered virtual DOM tree is not matching server-rendered content. This is likely caused by incorrect HTML markup, for example nesting block-level elements inside , or missing . Bailing hydration and performing full client-side render.
Ok, I found out what was wrong.
I was trying to do this :
<base-gallery client-only :items="items" :gallery-id="123" />
But it should be like this :
<client-only>
<base-gallery :items="items" :gallery-id="123" />
</client-only>

VueJS - Function to display image

I'm new to VueJS and having a hard to on this situation.
display.vue
<template>
<img :src="getLogo(logo)" />
</template>
<script>
export default {
methods: {
getLogo(logo){
return '../assets/'+logo;
}
}
}
</script>
I got an 404 error on that code.
But I tried not using the getLogo() function and it displayed.
<template>
<img src="../assets/logo.svg" />
</template>
The image structure is:
src/assets/logo1.svg
webpack.base.conf.js
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
Anybody here can help me displaying the image by using the getLogo function? Thank you very much!
I reckon when using v-bind:src it should be as follows
<img v-bind:src="'../assets/logo.svg'">
<!-- or shorthand -->
<img :src="'../assets/logo.svg'">
Notice the ' '
While using <img src="../assets/logo.svg" /> you do not need to bind a string, hence that's why it works.