Vue cli image wont load with webpack - vue.js

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!

Related

Background image issue with local images when i use bg in div

I have a issue in tailwind css when i use bg-"[url('.assets/images.png')]" these is not working when i put online image address the image is coming what could be the issue with local images as i frustrated doing and doing but not geeting any
solution
A explaination would be helpful and correct syntax would be helpful
In your code there is typo, url is outside the []
Change
bg-url['(<imagepath)']
to
bg-[url('<imagepath>')]
Extra: Procedure:
When using asset image make sure you add your own background images by editing the theme.backgroundImage section of your tailwind.config.js file:
tailwind.config.cs
module.exports = {
theme: {
extend: {
backgroundImage: {
'images': "url('.assets/images.png')", 👈 add your image here
}
}
}
}
Then use it as
<div class="bg-[url('/img/hero-pattern.svg')]">
<!-- ... -->
</div>
Refer: https://tailwindcss.com/docs/background-image
I don't know the syntax of tailwind css, but it looks like your path '.assets/images.png' is not valid because of the '.assets' part. Try to find out where your image are located in relation to your resulting css file.
If they are organized like
assets/
images/
css/
styles.css
you can write
bg-"[url('../images/images.png')]"
If it's like
assets/
images/
public/
css/
styles.css
you can write
bg-"[url('../../assets/images.png')]"
But as I said I don't know tailwind.
After seeing your Screenshot and the organization of your files I think that
class= "bg-url[('Assets/images.png')]"
will lead to success, because your assets folder is located in the same folder as your index.html and it seems a good idea to write the path inside the quotation marks, not the brackets.

How to properly load Bootstrap5's Masonry into Nuxt?

I am trying to use the Masonry plugin with Bootstrap5 and NuxtJS. When I follow the example here
https://getbootstrap.com/docs/5.0/examples/masonry/ and incorporate it into my own codesandbox, I notice that my demo is not in the correct masonry format. See the gaps? My sandbox
My example:
Bootstrap's example:
What do I need to do to get my demo into format shown on the Bootstrap Masonry example page?
I checked how to load the script from a CDN either globally or locally. It was working but at one condition: you needed to NOT start on the masonry page.
Meaning that if you loaded the app on a specific page, then moved to the one with the masonry it was working. But not if you started on this specific page. So, a pretty subpar solution.
This article was really helpful to understand how to wait until the CDN script is fully loaded: https://vueschool.io/articles/vuejs-tutorials/how-to-load-third-party-scripts-in-nuxt-js/
Then I realized that we are far better installing it directly as an NPM dependency. Therefore, I proceeded to the masonry repo. Found a great message on how to setup the whole thing in Nuxt.
And after a removal of some useless stuff and some modern dynamic import, here we are
<template>
<main>
<h1>Bootstrap and Masonry</h1>
<div class="row" id="masonry">
<!-- ... -->
</main>
</template>
<script>
export default {
async mounted() {
if (process.browser) {
let { default: Masonry } = await import('masonry-layout')
new Masonry('#masonry', { percentPosition: true })
}
},
}
</script>
The final solution is looking pretty well and there is not a lot of code. On top of that, the code is properly loaded. And you can load it on a click or any other event.

attribute binding in vue 3

I'm new to Vue and currently trying to dynamically change the video or image source link by passing the data in through a prop. I created a component with specific template structure that I would like to pass in the source from the main app.js page. I've tried binding it in both areas but unsure if I'm doing it correctly. I tried using regular divs and stuff to embed the video in app.js and it shows the content perfectly.
parent element contains 'Video' component-
<Video theme="IL" :vidSrc="srcIL.vid"></Video>
import Video from "./components/Video.vue";
export default {
name: "App",
components: {
Video
},
data() {
return {
srcIL: {
vid: "./assets/invi-lines/invisible-lines-film.mp4"
}
};
}
child 'Video component'
<template>
<div class="introVid top">
<video controls :src="vidSrc"></video>
</div>
</template>
<script>
export default {
props: ["theme", "vidSrc"]
};
</script>
This seems like you have it set up properly, and it is hard to know exactly what is causing the issues from the info provided, but I'm going to make a guess that it might be that the asset is not getting bundled.
I tried using regular divs and stuff to embed the video in app.js and it shows the content perfectly
I suspect you had something like:
<video controls src="./assets/invi-lines/invisible-lines-film.mp4"></video>
which would have taken the resource from the assets and packaged it for use.
see relative-path-imports for details.
You can try forcing these to load using require somewhere in the project, which will force the compiler to copy the asset, but really, if you have dynamic assets (assuming there's more than a handful and they can change) you should have them in the public folder already, not in the source folder. So my recommendation is that you move the dynamic assets to the public folder (assuming that was your issue to begin with)

Vue Template - Making any URLs found in returned text string to a link

I am working on a project that is Vue modular based (code used is: https://github.com/mishushakov/dialogflow-web-v2/blob/bc3ce7d7cf8e09a34b5fda431590bd48cc31f66b/src/App.vue)
Linking to the file I think need to make the change to, have been trying but I don't really know Vue at all and had not luck.
The returned message is plain text for example: this is a test message, please visit https://wwww.google.com
What I am trying to do, is from that text string, if a URL found is to create a link from that found URL
<RichComponent><RichBubble v-if="message.queryResult.fulfillmentText" :text="message.queryResult.fulfillmentText" /></RichComponent>
Is what the current code is that returns the data.
Is there a best way to achieve this? Is there a core function maybe?
I have tried to npm install linkify but cannot seem to get it working so maybe a direct approach would be better?
You can use linkifyjs to convert links in a string into anchor tags. The linkifyjs/lib/linkify-string.js file augments the String prototype with a linkify() method.
<template>
<p v-html="msg.linkify()"></p>
</template>
<script>
import 'linkifyjs/lib/linkify-string' // side effect: creates String.prototype.linkify
export default {
props: ['msg'],
}
</script>
It also exports that method if you prefer an explicit call:
<template>
<p v-html="linkify(msg)"></p>
</template>
<script>
import linkify from 'linkifyjs/lib/linkify-string'
export default {
props: ['msg'],
methods: {
linkify,
}
}
</script>

Vuelayers vl-style-icon syntax

I've been looking through the vuelayers documentation and have found little info on to use the vl-style-icon module, which is quite important if you want to create icons on your vuelayer map.
I'm pretty sure I have proper syntax when it comes to using it but marker.png won't load in through it. I've tried accessing it as just a normal image and it works fine so it is to my assumption that it's something with my syntax.
Here is my code:
<template>
<vl-map :load-tiles-while-animating="true" :load-tiles-while-interacting="true" style="height: 400px">
<vl-view :zoom.sync="zoom" :center.sync="center" :rotation.sync="rotation" projection="EPSG:4326"></vl-view>
<vl-feature v-for="crime in crimePoints" :key="crime.id">
<vl-geom-point :coordinates="crime.coords"></vl-geom-point>
<vl-style-box>
<vl-style-icon src="./marker.png" :scale="0.4" :anchor="[0.5, 1]"></vl-style-icon>
</vl-style-box>
</vl-feature>
<vl-layer-tile>
<vl-source-osm></vl-source-osm>
</vl-layer-tile>
</vl-map>
</template>
vl-style-box and vl-style-icon are the main points here. I have also checked to see if the points come up without vl-style-box and they do. What could be wrong with my code?
You can try like this:
<vl-style-icon :src="require('./marker.png')" :scale="0.4" :anchor="[0.5, 1]"></vl-style-icon>
</vl-style-box>
If you used Vue CLI to create your vue project include this in your vue.config.js file. First section tells webpack to parse url attribute on custom tags other than what is already configured (Source).
module.exports = {
chainWebpack: config => {
config.module.rule('vue').use('vue-loader').tap(options => {
options.transformAssetUrls = {
'vl-style-icon': 'src',
...options.transformAssetUrls,
};
return options;
});
}
}
Run the following command to verify the correct vue-loader configuration is there
Source
vue inspect > output.js