Template slot in buefy carousel showing broken image - vue.js

Hi i am newbie in vuejs and buefy. I wanted to do a carousel. However its already printing in the b-carousel-item but in template slot="indicators" it showing broken image. Can anyone help me i want to show the image also in the template slot
this is the code:
https://codesandbox.io/s/wonderful-gagarin-5wc8d?file=/src/App.vue
App.vue
<template>
<b-carousel :indicator-inside="false">
<b-carousel-item v-for="(item, i) in imgurl" :key="i">
<span class="image">
<img :src="getImgUrl(item)" />
</span>
</b-carousel-item>
<template slot="indicators" slot-scope="props">
<span class="al image">
<img :src="getImgUrl(props.item)" :title="props.item" />
</span>
</template>
</b-carousel>
</template>
<script>
export default {
data() {
return {
thumbs: null,
imgurl: [
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTE7e4ENLA4IRiYClFOOyc418WmdNTuWAAX_A&usqp=CAU",
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQrMMLeNArJ-NmM-sRGGGr0ya8y0NSF4HZ8Aw&usqp=CAU",
],
};
},
methods: {
getImgUrl(value) {
this.thumbs = value;
return `${value}`;
},
},
};
</script>

Related

How to change styles of child component based on grid / list toggled in parent component, in vue?

I have a view in Vue project.
Home.vue
<template>
<TestLayout >
<Card/>
<Card/>
<Card/>
</TestLayout>
</template>
<script>
import TestLayout from "../components/TestLayout.vue"
import Card from "../components/Card.vue"
export default {
name: "Home",
props:{
isList:{
type: Boolean
}
},
components: {
TestLayout,
Card
},
}
</script>
The TestLayout has a section where we can display cards in list or grid view
TestLayout.vue
<template>
<div class="flex border-solid ">
<ListBulletIcon class="h-10 w-10 cursor-pointer shadow border-2 border-indigo-600 rounded-l p-2"
#click="listView = true" />
<TableCellsIcon #click="listView = false"
class="h-10 w-10 cursor-pointer shadow border-2 border-indigo-600 rounded-r p-2" />
</div>
<section
:class="[listView ? 'md:grid-cols-1 grid-cols-1' : 'md:grid-cols-4 grid-cols-2', 'rounded-md grid gap-5 col-span-full']">
<slot :listView="listView"></slot>
</section>
</template>
<script>
import {
ListBulletIcon,TableCellsIcon} from '#heroicons/vue/24/outline'
export default {
data: function () {
return {
listView: false,
}
},
components: {
ListBulletIcon,
TableCellsIcon,
},
}
}
</script>
I want to change the style of Card.vue based on whether user clicks grid view or list view icon.
For example, I want to add this style to Card.vue div tag in its template:
:class="[isList ? 'dark:bg-midnight' : 'dark:bg-red-300', 'min-h-80 w-full bg-gray-50 shadow-xl rounded-md flex flex-col']"
How will I check isList is clicked or not?
How can I achieve this?
You're half way there. After defining a slot prop (<slot :listView="listView"></slot>) you should access it in parent and pass it down to slot components.
<TestLayout>
<template v-slot="{ listView }">
<Card :isList="listView" />
<Card :isList="listView" />
</template>
</TestLayout>

PrimeVue Toast displaying html tags

How can I implement displaying a link in a primevue toast message? I cannot use v-html directive and triple brackets do not work. Does anybody has another idea how to solve it?
A hacky way is to extends Toast component:
Here a codesandbox : https://codesandbox.io/s/extend-primevue-toast-o5o1c?file=/src/CustomToastMessage.vue
1. On your component
Import your custom toast component where you need to call this.$toast:
<template>
<div>
<CustomToast />
<CustomToast position="top-left" group="tl" />
<CustomToast position="bottom-left" group="bl" />
<CustomToast position="bottom-right" group="br" />
<div class="card">
<Button #click="test" label="test" />
</div>
</div>
</template>
<script>
import CustomToast from "./CustomToast.vue";
export default {
components: {
CustomToast,
},
data() {
return {
messages: [],
};
},
methods: {
test() {
this.$toast.add({
severity: "success",
summary: "Test",
detail: "<b>Test Bold</b>",
});
},
},
};
</script>
2. CustomToast.vue (extend primevue toast)
<template>
<Teleport to="body">
<div ref="container" :class="containerClass" v-bind="$attrs">
<transition-group name="p-toast-message" tag="div" #enter="onEnter">
<CustomToastMessage
v-for="msg of messages"
:key="msg.id"
:message="msg"
#close="remove($event)"
/>
</transition-group>
</div>
</Teleport>
</template>
<script>
import Toast from "primevue/toast/Toast.vue";
import CustomToastMessage from "./CustomToastMessage.vue";
export default {
extends: Toast,
components: {
CustomToastMessage,
},
};
</script>
3. CustomToastMessage (extend primevue toastmessage)
Add v-html where you want to have html
<template>
<div
:class="containerClass"
role="alert"
aria-live="assertive"
aria-atomic="true"
>
<div class="p-toast-message-content">
<span :class="iconClass"></span>
<div class="p-toast-message-text">
<span class="p-toast-summary">{{ message.summary }}</span>
<div class="p-toast-detail" v-html="message.detail"></div>
</div>
<button
class="p-toast-icon-close p-link"
#click="onCloseClick"
v-if="message.closable !== false"
type="button"
v-ripple
>
<span class="p-toast-icon-close-icon pi pi-times"></span>
</button>
</div>
</div>
</template>
<script>
import ToastMessage from "primevue/toast/ToastMessage.vue";
export default {
extends: ToastMessage,
};
</script>
There is an easiest solution.
Just implement your own template.
Example:
<Toast :position="toastPosition">
<template #message="slotProps">
<span :class="iconClass"></span>
<div class="p-toast-message-text">
<span class="p-toast-summary">{{slotProps.message.summary}}</span>
<div class="p-toast-detail" v-html="slotProps.message.detail" />
</div>
</template>
</Toast>

How can I write emit even to tell parent is icon is clicked in Vuejs

I am write input element with icon to show/hide password, how can I write event emit in v-icon to tell parent component that icon is click
Here is my child component BaseInputPassword
<div class="label">
{{ labelName }} <span v-if="required" class="required">※</span>
</div>
<div class="input_password">
<input
:type="type ? 'password' : 'text'"
:placeholder="placeholder"
/>
<v-icon #click="type =! type">{{ type ? "mdi-eye-off" : "mdi-eye" }}</v-icon>
</div>
</div>
</template>
<script>
export default {
props: ["labelName", "placeholder", "required", "type" ],
data() {
return {
};
},
methods: {
updateValue($event) {
this.$emit("input", $event);
},
}
}
</script>
Here is my parent component, im using three child component
<div class="input_area">
<BlockInputPassword labelName="現在のパスワード" required="true" :type="show1" v-model="password" ></BlockInputPassword>
<BlockInputPassword labelName="現在のパスワード" required="true" :type="show2" v-model="password" ></BlockInputPassword>
<BlockInputPassword labelName="新しいパスワードの確認" required="true" :type="show3" v-model="password"></BlockInputPassword>
</div>
</div>
<div class="footer">
<router-link to=""
><div class="btn_login btn_simple">
キャンセル
</div></router-link>
<router-link to=""
><div class="btn_login btn_simple status_color_4">
変更
</div></router-link>
</div>
</div>
</div>
</template>
<script>
import BlockInputPassword from "../components/common/BlockInputPassword"
export default {
components: {
BlockInputPassword,
},
name: "PasswordChange",
data() {
return {
password: '',
show1: false,
show2: false,
show3: false,
};
},
have you child component v-icon emit a custom event
<v-icon #click="$emit('icon-clicked')">
then from the parent component
<div class="input_area">
<BlockInputPassword #icon-click="doSomething" ...></BlockInputPassword>
...
</div>

How to get the value of one input field in a "v-for" of multiple inputs

I have multiple text inputs generated in v-for directive which i have attached to one v-model variable as show below. I have a button by the respective inputs which prints the value of the current working input. Ultimately I want to extract value of the selected input without affecting the other inputs.
But apparent any change make in one input affect all the input. I super confused as to how I will achieve this. Any help will be much appreciated.
My attempted code is shown below.
<template>
<div id="app">
<div v-for="i in 5" :key="i">
<input v-model="text" type="text" :key="i" />
<button #click="printText">print</button> <span>{{ text }}</span>
</div>
</div>
</template>
<script>
export default {
data() {
return {
text: "",
};
},
methods: {
printText() {
console.log(this.text);
},
},
};
</script>
Take an array instead of simple variable when you use v-model in v-for
And on click pass the index with function call
Try to use
<template>
<div id="app">
<div v-for="i in 5" :key="i">
<input v-model="text[i]" type="text"/>
<button #click="printText(i)">print</button> <span>{{ text[i] }}</span>
</div>
</div>
</template>
<script>
export default {
data() {
return {
text: [],
};
},
methods: {
printText(index) {
console.log(this.text[index]);
},
},
};
</script>

bootstrap-vue : how to recognize hover event over b-tab

I'm trying to change the active tab of a bootstrap-vue b-tabs when the tab title is hovered over, not only when clicked on. I'm having trouble isolating this event.
In the following Codepen example, I can isolate the event when the image is being hovered over, however I want to isolate the event when the title ('Tubes and Vials' for example) is being hovered over.
I'm fairly new to Vue so I apologize if this is a simple answer, but I haven't struggled with this for a while now and haven't been able to figure this out. Thanks!
Component File
<template>
<b-container class="px-3" fluid>
<div>
<h3>Range Of Glass Products We Inspect</h3>
<p>Anything formed from tubular glass</p>
</div>
<div>
<b-tabs content-class="mt-3" align="left" class="vial-types" vertical>
<b-tab
v-for="glassItem in productRange"
v-bind:key="glassItem.type"
v-bind:ref="glassItem"
v-bind:title="glassItem.type"
#mouseover.native="greet()"
#mouseleave.native="greet()"
>
<b-img
v-bind:src="glassItem.image"
alt="Factory Image">
</b-img>
</b-tab>
</b-tabs>
</div>
</b-container>
</template>
<script>
export default {
name: "ProductRange",
data() {
return {
productRange: [
{type: "Screw & Flanged Head", image:"https://picsum.photos/600/400/", hover: false},
{type: "Tubes and Vials", image:"https://picsum.photos/600/400/", hover: false},
{type: "Pipettes, Syringes, Filling Needles", image:"https://picsum.photos/400/400/",hover: false},
{type: "Ampoules", image:"https://picsum.photos/600/400/", hover: false},
{type: "Custom Geometries Per Customer Specification", image:"https://picsum.photos/600/400/", hover: false}
]
}
},
methods: {
greet: function () {
console.log("Hovering");
}
}
}
</script>
<style lang="sass">
</style>
You could also use the b-tab's title slot, and then add a hover/unhover listener in there:
<b-tabs content-class="mt-3" align="left" class="vial-types" vertical>
<b-tab
v-for="glassItem in productRange"
v-bind:key="glassItem.type"
v-bind:ref="glassItem"
>
<template v-slot:title>
<div
#mouseover="hovered"
#mouseleave="unHovered"
>
{{ glassItem.type }}
</div>
</template>
<b-img
v-bind:src="glassItem.image"
alt="Factory Image">
</b-img>
</b-tab>
</b-tabs>
Sadly I don't think there's a built-in way to easily do this.
However, you can still solve this by hiding the standard tabs and instead reconstruct the structure yourself using b-nav and binding to the b-tabs v-model.
You can then add your events the b-nav-item as they'll be working as your tabs.
new Vue({
el: "#app",
data: {
selectedTab: 0,
productRange: [
{
type: "Screw & Flanged Head",
image: "https://picsum.photos/600/400/"
},
{
type: "Tubes and Vials",
mage: "https://picsum.photos/640/400/"
},
{
type: "Pipettes, Syringes, Filling Needles",
image: "https://picsum.photos/400/400/"
},
{
type: "Ampoules",
image: "https://picsum.photos/600/400/"
},
{
type: "Custom Geometries Per Customer Specification",
image: "https://picsum.photos/700/400/"
}
]
},
methods: {
greet: function() {
console.log("hovering");
},
onTabHover(glassItem) {
console.log("Tab hovered", glassItem)
}
}
});
<link href="https://unpkg.com/bootstrap#4.4.1/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://unpkg.com/bootstrap-vue#2.4.2/dist/bootstrap-vue.css" rel="stylesheet"/>
<script src="https://unpkg.com/vue#2.6.10/dist/vue.min.js"></script>
<script src="https://unpkg.com/bootstrap-vue#2.4.2/dist/bootstrap-vue.min.js"></script>
<b-container id="app" class="px-3"fluid>
<div>
<h3>Range Of Glass Products We Inspect</h3>
<p>Anything formed from tubular glass</p>
</div>
<div>
<b-row>
<b-col cols="auto">
<b-nav pills vertical>
<b-nav-item v-for="(glassItem, index) in productRange"
:active="selectedTab === index"
#click="selectedTab = index"
#mouseenter="onTabHover(glassItem)">
{{ glassItem.type }}
</b-nav-item>
</b-nav>
</b-col>
<b-col>
<b-tabs v-model="selectedTab"
content-class="mt-3"
class="vial-types"
nav-class="d-none">
<b-tab
v-for="glassItem in productRange"
:key="glassItem.type"
:ref="glassItem"
:title="glassItem.type"
#mouseover.native="greet()"
#mouseleave.native="greet()"
>
<b-img
:src="glassItem.image"
alt="Factory Image">
</b-img>
</b-tab>
</b-tabs>
</b-col>
</b-row>
</div>
</b-container>