Vue js image not showing for image path problem - vue.js

This is a laravel vue project. My Image directory "public/images/products". My Database image data is "image":"images/products/image_name.jpg". My Route path is "127.0.0.1:8000/product". In this route path image showing without a problem. when my route 127.0.0.1:8000/product/:slug, here my image not showing. Here I inspect element the browser and I see the image path looks like 127.0.0.1:8000/product/:slug/images/products/image_name.jpg. Now How I Fix The Image Link.
My Router.Js
{ path: '/product/:slug', component: require('./components/public/singleProduct.vue').default },
My Vue File
<li v-for="data in product.product_images">
<img :src="data.image" class="img-fluid"/>
</li>

You can use absolute path, works anywhere (I mean, no matter what current path is).
<img :src="'/' + data.image" class="img-fluid"/>

Related

How to add image locally in a Vue?

I want to add a photo to my project, but for some reason it doesn't want to add locally
Can someone help me how to do this?
template:
<li v-for="book in books" :key="book.id">
*Some code here*
<img :src="book.image"/> <<<-----Here
</li>
script:
export default {
data() {
return{
books: [
image: "../assets/images/a-Dolls-house.jpg"
]
}
}
}
Change <img :src="book.image"/> to <img :src="require(book.image)"/>
This will work because the assets folder is not public to the browser. Meaning that when you try to call from the assets folder it cannot find the path specified because the webserver cannot find the assets folder. However by calling require we load the image from the assets folder, and convert it to a base 64 encoded image. Which can be seen by the browser as it is compiled into your chunk.
The other option you have is to move your images folder to the public directory and change your image property to image: "/images/a-Dolls-house.jpg". Then the image will be public and can be accessed from the browser. Without increases your chunk sizes, or increasing your memory overhead, as the images would be linked instead of compiled.

Creating a path to an asset dynamically

The issue is how to get Vue to render the correct path for an asset, if the path to the asset and the assets name is passed through as a props.
Explanation:
When using a Vue component... if passing in props which contain a path and a file name of an asset to be loaded
export default{
name: 'NewComponent',
props: ["path","file"],
computed:{
calculateCompletePath (){
return this.path+""+this.file;
}
}
}
If using something like the above in a manner such as:
<template>
<div>
<video>
<source :src="calculateCompletePath" type="video/mp4"/>
</video>
</div>
</template>
How can you get the src portion to render correctly - e.g Vue generates its own string referencing the media folder for example
/media/movie.6ac43bcf.mp4
Side note:
I've read somewhere there is the possibility to using require (<<asset>>) but that doesn't seem to work if used on the computed function e.g. return require (this.path+""+this.file);
Any ideas how to get this to work?
Please refer this document for a detailed explanation on how to resolve static assets:
https://cli.vuejs.org/guide/html-and-static-assets.html#relative-path-imports
I think the problem is that your asset(in this case an mp4 file) is not located in your computer's /media folder.
See these 3 points for a better understanding: https://cli.vuejs.org/guide/html-and-static-assets.html#url-transform-rules
If your media folder is located under the root folder(/), then, the computed value /media/movie.6ac43bcf.mp4 will work.
If your media folder is under src folder of the app, your computed property should return #/media/movie.6ac43bcf.mp4
If your media folder is somewhere else, then you should create a proper path using #/ or the ./ symbol to reach the file correctly.

Vue cli image wont load with webpack

What am I doing?
I am using the intersection observer API to make lazy loading.
What have I tried?
I tried the code in a simple HTML page and it works perfect, but when I use the code in vue, the images won't load (local images). If I put a htttp source images (online images) it works perfect, too. I think this is a webpack error config. Am I right? How can I fix it?.
Whats the error?
When i use a local image the code doesnt work, if only change that src with something else like this image https://images.pexels.com/photos/69817/france-confectionery-raspberry-cake-fruit-69817.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940 the code WORKS, why i cant make it work with local images?
HTML AND SCRIPT
<template>
<div class="container" id="section3">
<span class="containerTitle">Galeria</span>
<div class="wrapper">
<img v-lazyload data-src="#assets/images/001.jpg" class="card">
</div>
</div>
</template>
<script>
import lazyload from '../directives/lazyload'
export default {
directives:{
lazyload
},
}
</script>
DIRECTIVE
export default{
inserted: el =>{
const options = {
// root:
rootMargin: '0px 0px 0px 0px',
threshold:1
}
var observer = new IntersectionObserver((entries,observer) =>{
entries.forEach(entry => {
if(entry.isIntersecting){
el.src = el.dataset.src
observer.unobserve(el)
console.log('intersecting');
}
})
},options)
observer.observe(el)
}
}
CODE IMAGE
FOLDER
The issue is with your image path.
You can fix it with either using public folder and give it in path.
You can also check for auto suggestion which come up while typing, this may help you to check whether your path is correct or not.
Like this
Your path is wrong. You gave ../assets/images/001.jpg as the path to the image (as stated in your question), but according to your directory tree it's ../assets/001.jpg (or write it like #/assets/001.jpg, # points to root of project). That should fix it.
As far as I remember you can't use # sign inside <template>.
So you can either:
require it
<img v-lazyload :data-src="require('#assets/images/001.jpg')" class="card">
import it
<template>
...
<img v-lazyload data-src="image" class="card">
...
</template>
<script>
import img from '#assets/images/001.jpg';
...
data() {
return {
image: img,
}
}
...
</script>
use relative path
<img v-lazyload data-src="../assets/images/001.jpg" class="card">
You can check how it works in Vue docs
I can't remember why this works, but you need to use the following syntax:
<img v-lazyload data-src="~assets/images/001.jpg" class="card">
with the ~ replacing the ../.
I will update the answer if I figure out exactly why.
doing extensive research i found this article about vuejs and static assets.
https://edicasoft.com/weblog/2018/04/27/static-vs-srcassets-webpack-template-vue-cli/
They said that this kind of problems occurs "because" of webpack,like i though, so the solution for this (i hope not the only solution), but this is the solution so far...
QUOTE
All asset URLs such as , background: url(...) and CSS #import are resolved by Webpack as module dependencies like require('./logo.png').
We then use loaders for Webpack, such as file-loader and url-loader, to process them. Webpack template has already configured these loaders.
File-loader helps to determine the final file location and how to name it using version hashes for better caching. Thus you can put your static assets near your .vue files and use relative paths. There is no need to put them strictly into the ‘assets’ folder.
Url-loader helps to conditionally inline assets such as base64 data URL, reducing the amount of HTTP requests.
So what the hell should I do with it?
The answer is: put your assets in the ‘src’ folder.
I tested this and it works perfect BUT you CANT make a subfolder and this for me, is disorganized.
This is the final folder structure to get this done using intersection observer api as vue directive!

Vue V-Bind:src always includes local server "localhost:8080" at the beginning. How to set to src to different server?

I am building a web app using vue. I am trying to load images of a strapi cms that I am running and include them via an v-for loop in my component.
When setting the :src for an image, vue always includes the local server that my vue app is running on at the beginning. How do I get around that, so that I can reach the CMS on another port?
I tried different methods of binding the source, including "v-bind:src", ":src", ":src="require()""
<div class="images">
<template v-for="(Image, index) in Images">
<p v-bind:key="index">{{Image.Image_URL}}</p>
<img v-bind:key="index" :src="Image.Image_URL" :v-bind:alt="Image.Titel">
</template>
</div>
​​
Output of one of the json objects.
Date: "24.04.2019",​
Place: "Beijing, China",
​​
Id: 2,
​​
Image_URL: "http:/localhost:1337/uploads/ca472ad50d814fbb963e8b5a5b12742d.jpg",
​
Title: "Lights"
I get the image url in a json object. The final url, which is represented here as "Image.Image_URL" is something like: "localhost:1337/uploads/ca472ad50d814fbb963e8b5a5b12742d.jpg". Until now the image src is always get "http://localhost:8080/localhost:1337/uploads/ca472ad50d814fbb963e8b5a5b12742d.jpg" in Vue.
Thanks guys
You are missing one more slash in http:/localhost:1337/uploads/ca472ad50d814fbb963e8b5a5b12742d.jpg, should be http://

Vue router: anchor links to a specific place in a page e.g. /route/#anchor

Is there an established way to use vue-router (router-link) to link to a specific route, including an anchor on a page?
I can do this: <router-link to="/page/#section"> and the router will work as expected, but only if I am on the actual /page/ location – it will scroll to the nearest element with id="section"
But if I use the same router-link from elsewhere (eg. /page2/) the router will return 404, because it will treat the /#section part as a nested route.
1.
Install vue-scrollto:
npm install --save vue-scrollto
2.
Setup main.js:
import VueScrollTo from 'vue-scrollto'
Vue.use(VueScrollTo)
3.
Set anchor ids (most likely in your Home.vue):
<template>
<v-content>
<SectionOne id="section-one"/>
<SectionTwo id="section-two"/>
<SectionThree id="section-three"/>
</v-content>
</template>
4.
Link to anchor via href or router-link:
via href:
<a href="#" v-scroll-to="'#section-one'">
Scroll to #section-one
</a>
via router-link:
<router-link to="#" v-scroll-to="'#section-two'">
Scroll to #section-two
</router-link>
Here is a solution for router links pointing to an anchor on a different page:
Use this link syntax: <router-link to="/page#section">. On the target page you need add your own scroll logic:
mounted() {
var section=this.$router.currentRoute.value.hash.replace("#", "");
if (section)
this.$nextTick(()=> window.document.getElementById(section).scrollIntoView());
},
This works quite well but you might want to add a bit of error handling for non-existent anchors.
There's an example in the vue-router docs where they simulate the "scroll to anchor" behaviour: https://router.vuejs.org/guide/advanced/scroll-behavior.html
Example they link to near the bottom of the page:
https://github.com/vuejs/vue-router/blob/dev/examples/scroll-behavior/app.js
I haven't tried it myself (yet), but appears to work for them.