Carousel prime vue width decreases - vue.js

The first slide has a normal width, but each subsequent one has less and less. Although I strictly follow the doc(. Please help me figure it out.
link to the website: https://hydralux-74de0.web.app/
Here is my code:
<Carousel :value="images" :numVisible="1" :numScroll="1">
<template #item="slotProps">
<div class="carousel-data">
<img :src="slotProps.data.src" height="300">
</div>
</template>
</Carousel>
and
const images = ref([
{src: new URL('../assets/img/sewage-system/01.jpeg', import.meta.url)},
{src: new URL('../assets/img/sewage-system/02.jpeg', import.meta.url)},
{src: new URL('../assets/img/sewage-system/03.jpeg', import.meta.url)},
{src: new URL('../assets/img/sewage-system/04.jpeg', import.meta.url)},
{src: new URL('../assets/img/sewage-system/05.jpeg', import.meta.url)},
]);

Related

if-emoji lookup table with Vue

I'm using the npm module if-emoji to detect whether a user can view emojis or not. There is a similar tool in Modernizr.
If the user can't view emojis, I'm displaying an image of the emoji instead. So my Vue HTML looks like this:
<h2 v-if="this.emojis">😄</h2>
<h2 v-if="!this.emojis"><img src="https://example.com/emoji.png">/h2>
Does this still download the image for users who can view emojis, therefore using bandwidth unecessarily?
And is there a more efficient way of doing this, so that I don't need to go and add v-if every time I use an emoji? Can there be some sort of lookup table, if there's an emoji and !this.emojis?
You can solve this also by creating your own vue.component
<emojiorimage usesmily="false" smily="😄" imgpath="https://i.stack.imgur.com/QdqVi.png"></emojiorimage>
that capsulates the decision if image or smily inside itself.
var app = new Vue({
el: "#app",
data: function(){
return {
extendedCost: 0,
}
},
components: { "emojiorimage" : {
template : `
<h2>
usesmily is {{usesmily}}<br/>
<div v-if="usesmily === 'true'">{{ smily }}</div>
<div v-else><img :scr="imgpath" width="50" height="50" :alt="imgpath" /></div>
</h2>`,
props: ["usesmily", "smily", "imgpath"],
}}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h1>Emoji or Image</h1>
<emojiorimage
usesmily="false"
smily="😄"
imgpath="https://i.stack.imgur.com/QdqVi.png"
></emojiorimage>
<emojiorimage
usesmily="true"
smily="😎"
imgpath="https://i.stack.imgur.com/QdqVi.png"
></emojiorimage>
</div>
You can then feed it the isemoji from your npm package that you query once and store somewhere.
For seperate vue files it would look kind of like this:
emojiorimage.vue
<template>
<h2>
<div v-if="usesmily === 'true'">{{ smily }}</div>
<div v-else><img :scr="imgpath" width="50" height="50"
:alt="imgpath" /></div>
</h2>
</template>
<script>
export default {
props: ["usesmily", "smily", "imgpath"],
};
</script>
App.vue
<template>
<div id="app">
<h1>Emoji or Image</h1>
<emojiorimage
usesmily="false"
smily="😄"
imgpath="https://i.stack.imgur.com/QdqVi.png"
/>
<emojiorimage
usesmily="true"
smily="😎"
imgpath="https://i.stack.imgur.com/QdqVi.png"
/>
</div>
</template>
<script>
import emojiorimage from "./components/emojiorimage.vue";
export default {
components: {
emojiorimage,
},
};
</script>
index.html
<div id="app"></div>
index.js
import Vue from "vue";
import App from "./App";
Vue.config.productionTip = false;
new Vue({
el: "#app",
template: "<App/>",
components: { App }
});
to get:
Learning resources:
https://v2.vuejs.org/v2/guide/components.html
https://v2.vuejs.org/v2/guide/single-file-components.html
This should work as well:
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<h2 v-if="true">😄</h2>
<h2 v-else><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/e/e0/SNice.svg/1200px-SNice.svg.png" width=15 height=15></h2>
<h2 v-if="false">😄</h2>
<h2 v-else><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/e/e0/SNice.svg/1200px-SNice.svg.png" width=15 height=15></h2>
The v-if part only is part of the sourcecode if the statement is true - else the else statement is in instead. If the img tag is not part of the loaded source the image wont be loaded.
<h2 v-if="emojis">😄</h2>
<h2 v-else><img src="https://example.com/emoji.png"></h2>
Is probably the only way to improve your code as #Patrick Artner pointed out.
You do not need this. in the template
To the question if the image is loaded if it is not shown the simple answer is no. Vue only renders v-ifs when they are needed and does not render it - the image is loaded only if !emojis.
Thanks to #PatrickArtner who posted the idea of using a Vue component to render the emoji / image. Here is my final solution, which resizes the emoji / image to fit the surrounding text — it uses fitty to resize the emojis, and sets the images to height:1em;.
Emoji.vue
<template>
<div class="emojiContainer">
<span id="fittyEmoji" v-if="emojis">{{ insert }}</span>
<img v-if="!emojis" :src="insert" class="emojiImage">
</div>
</template>
<style scoped>
.emojiContainer {
display: inline;
}
.emojiImage {
height:1em;
}
</style>
<script src="fitty.min.js"></script>
<script>
import fitty from 'fitty';
import ifEmoji from 'if-emoji'
export default {
name: 'Emoji',
props: ['name'],
data: function() {
return {
insert: "",
emojis: false,
}
},
methods: {
insertEmoji(){
var names = ['frog', 'fire']
var emojis = ['🐸','🔥']
var urls = ['https://example.com/frog.png',
'https://example.com/fire.png']
if (this.emojis) {
this.insert = emojis[names.indexOf(this.name)];
} else {
this.insert = urls[names.indexOf(this.name)];
}
fitty('#fittyEmoji')
}
},
beforeMount() {
if (ifEmoji('🐸')) {
this.emojis = true;
} else {
this.emojis = false;
}
this.insertEmoji();
}
}
</script>
Then in your parent components you can just insert like this:
<template>
<div id="app">
<h1><Emoji name='frog'/> Frog Facts</h1>
<p>Lorem ipsum <Emoji name='fire'/><p>
</div>
</template>
<script>
import Emoji from '#/components/Emoji.vue'
export default {
components: {
Emoji,
},
};
</script>

Vue 3 - scrolling not possible. No scrollbar on browser

I create with several v-for loops, some divs which are bigger that my screen. But there is no scrollbar on Firefox or Chrome. So they cut of my div and I can see just a part of the div.
Did I miss something on Vue?
Lot of Data but no scrollbar
Lot of data is fetched and stored in items
<template>
<div class="ChildAddItem">
<div>Searchbar placeholder</div>
<div class="ItemChoiche" v-for="(item, index) in items" :key="index">
<table>
<tr>
<td>{{item}}</td>
</tr>
</table>
<p v-if="item == null">Null</p>
<p>test</p>
</div>
</div>
</template>
<script>
export default {
data: () => ({
openItemsearch: false,
groupid: '',
playerid: '',
items: []
}),
mounted() {
this.$axios.get("getallData").then((response) => (this.items = response.data));
this.groupid = this.$route.params.group;
this.playerid = this.$route.params.player;
},
}
</script>
<style>
</style>
resolved by remove the postion: fixed in the navigation bar css

SwiperJS lazy loading - Image not displaying when using data-src as the guide says

I have been struggeling trying to implement SwiperJS to my Statamic 3 project.
I have a working carousel/slider that when not using data-src and lazy loading works perfectly fine. But as soon as I try to implement lazy loading following the guide on their website. I get either a white image/background with an infinite loader or a white image/background and no loader.
here is my code:
HTML (the images come from a antlers foreach):
<div class="flex flex-col w-1/3 p-2">
<div class="h-full w-full swiper-container">
<div class="h-48 swiper-wrapper">
{{ foreach:photos }}
<div class="swiper-slide">
<img data-src="{{ value:url }}" class="w-full h-full object-cover object-center swiper-lazy">
<div class="swiper-lazy-preloader"></div>
</div>
{{ /foreach:photos}}
</div>
<div class="swiper-pagination"></div>
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
</div>
</div>
My JS:
// core version + navigation, pagination modules:
import Swiper, { Navigation, Pagination } from 'swiper';
import 'swiper/swiper-bundle.css';
// configure Swiper to use modules
Swiper.use([Navigation, Pagination]);
var mySwiper = new Swiper('.swiper-container', {
slidesPerView: 1,
spaceBetween: 0,
slidesPerGroup: 1,
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
pagination: {
el: '.swiper-pagination'
},
mousewheel: false,
keyboard: true,
loop: true,
parallax: true,
grabCursor: true,
// Disable preloading of all images
preloadImages: false,
// Enable lazy loading
lazy: {
loadPrevNext: true,
},
});
Current result:
Anyone know why my images are not being rendered?
Kind regards,
Robbert
You need to import Lazy module.
Change
import Swiper, { Navigation, Pagination } from 'swiper';
to
import Swiper, { Navigation, Pagination, Lazy } from 'swiper';
and change
Swiper.use([Navigation, Pagination]);
to
Swiper.use([Navigation, Pagination, Lazy]);

can i change my font on a click in vuejs?

I am using Vuejs with vuetify components i have customize my website to have two languages with Internationalization (i18n).
the problem is i also want to change my font when i change to my second language bur don't know how to do that.
style
.font{
font-family: 'b nazanin';
/*i want to use this font after i change my language*/
}
<template>
<button v-for="entry in languages" :key="entry.title" #click="changeLocale(entry.language)"v-on:click="font">
<flag :iso="entry.flag" ></flag>
{{entry.title}}
</button>
<h1 v-bind:style="{font}">{{ $t('titleInHome') }}</h1>
</template>
can anyone please help me in this case thank you all
You can do it with style binding.
HTML Template:
<html>
<body>
<div id="app">
<h1 :style="styles">Apply font here</h1> <br>
<button v-for="entry in langs" #click="changeFont(entry.title)" :key="entry.title">
{{ entry.title }}
</button>
</div>
</body>
</html>
Script:
new Vue({
el:"#app",
data:{
styleObj:{
color :'blue',
border: '2px blue dotted',
backgroundColor:'gray',
fontFamily:'Time New Roman'
},
langs:[
{ title :'Vue.js'},
{ title:'React'},
{ title:'Angular'}
]
},
methods:{
changeFont(lang){
let fontFamily = null;
if(lang == "Vue.js"){
fontFamily = "Arial";
}
else if(lang == "React"){
fontFamily = "Verdana";
}
else{
fontFamily = "Calibri";
}
this.styleObj.fontFamily = fontFamily;
}
}
});
Complete Example
You can use a dynamic style or a dynamic class, these can depend on some variable inside your code. See here for example:
https://v2.vuejs.org/v2/guide/class-and-style.html#Object-Syntax-1
For example you could write two classes and then something like this:
:class="{'classOne': languageA: , 'classTwo': languageB}" //(languageA and B would be bools in this case)

Vue + Vuetify expansion panel enter/leave animation

I'm currently developing a webapp in Vue.js with the help of Vuetify.
I found the expansion panel element very usefull and I wanted to use it in my website.
So I easily get the data i want to display from Firebase and i proceed to load the items with this template:
<v-expansion-panel popout>
<v-expansion-panel-content
v-for="doc in filteredclienti"
:key="doc.id">
<div slot="header">{{doc.data().Nome}} {{doc.data().Cognome}}</div>
<v-card>
Card content
</v-card>
</v-expansion-panel-content>
</v-expansion-panel
Everything works fine, the panel is ok and the popup animation works fine too.
Now I'd like to display a simple enter/leave animation to each item.
I tried to add a <transition-group> tag after the <v-expansion-panel popuot> but the console tells me want only a <v-expansion-panel-content> element.
So i tried to add <transition-group> inside <v-expansion-panel-content> but in this case the layout is no more correct and the popup animation is not working anymore.
How can i do it? Thanks!
That should do the trick, I've added a delete button, that will slide the "deleted" doc out.
enjoy.
<template>
<v-app>
<v-expansion-panel popout>
<transition-group name="list" tag="v-expansion-panel">
<v-expansion-panel-content v-for="doc in filteredclienti" :key="doc.id">
<div slot="header">
<span>{{doc.data}}</span>
<v-btn class="error" #click="deleteItem(doc.id)">
<v-icon>delete</v-icon>
</v-btn>
</div>
<v-card>Card content</v-card>
</v-expansion-panel-content>
</transition-group>
</v-expansion-panel>
</v-app>
</template>
<script>
export default {
data: () => ({
filteredclienti: [
{ id: 1, data: "data1" },
{ id: 2, data: "data1" },
{ id: 3, data: "data1" },
{ id: 4, data: "data1" }
]
}),
methods: {
deleteItem(id) {
this.filteredclienti = this.filteredclienti.filter(d => d.id !== id);
}
}
};
</script>
<style>
.list-enter-active,
.list-leave-active {
transition: all 1s;
}
.list-enter,
.list-leave-to {
opacity: 0;
transform: translateX(100vw);
}
</style>