swiper-thumbs-gallery-loop-react not working in react js - slider

I'm facing an issue I want to create a swiper thumb gallery slider. the issue is that when I copy code from swiper js and paste it into my react app it's not working and getting an error called The above error occurred in the component:
while the same code is working in the code sandbox. Please help me to create the gallery thumb slider.
import React, { useRef, useState } from "react";
// Import Swiper React components
import { Swiper, SwiperSlide } from "swiper/react";
// Import Swiper styles
import "swiper/css";
import "swiper/css/free-mode";
import "swiper/css/navigation";
import "swiper/css/thumbs";
// import required modules
import { FreeMode, Navigation, Thumbs } from "swiper";
function App () {
const [thumbsSwiper, setThumbsSwiper] = useState(null);
return (
<>
<Swiper
loop={true}
spaceBetween={10}
navigation={true}
thumbs={{ swiper: thumbsSwiper }}
modules={[FreeMode, Navigation, Thumbs]}
className="mySwiper2"
>
<SwiperSlide>
<img src="https://swiperjs.com/demos/images/nature-1.jpg" />
</SwiperSlide>
<SwiperSlide>
<img src="https://swiperjs.com/demos/images/nature-2.jpg" />
</SwiperSlide>
<SwiperSlide>
<img src="https://swiperjs.com/demos/images/nature-3.jpg" />
</SwiperSlide>
<SwiperSlide>
<img src="https://swiperjs.com/demos/images/nature-4.jpg" />
</SwiperSlide>
<SwiperSlide>
<img src="https://swiperjs.com/demos/images/nature-5.jpg" />
</SwiperSlide>
<SwiperSlide>
<img src="https://swiperjs.com/demos/images/nature-6.jpg" />
</SwiperSlide>
<SwiperSlide>
<img src="https://swiperjs.com/demos/images/nature-7.jpg" />
</SwiperSlide>
<SwiperSlide>
<img src="https://swiperjs.com/demos/images/nature-8.jpg" />
</SwiperSlide>
<SwiperSlide>
<img src="https://swiperjs.com/demos/images/nature-9.jpg" />
</SwiperSlide>
<SwiperSlide>
<img src="https://swiperjs.com/demos/images/nature-10.jpg" />
</SwiperSlide>
</Swiper>
<Swiper
onSwiper={setThumbsSwiper}
loop={true}
spaceBetween={10}
slidesPerView={4}
freeMode={true}
watchSlidesProgress={true}
modules={[FreeMode, Navigation, Thumbs]}
className="mySwiper"
>
<SwiperSlide>
<img src="https://swiperjs.com/demos/images/nature-1.jpg" />
</SwiperSlide>
<SwiperSlide>
<img src="https://swiperjs.com/demos/images/nature-2.jpg" />
</SwiperSlide>
<SwiperSlide>
<img src="https://swiperjs.com/demos/images/nature-3.jpg" />
</SwiperSlide>
<SwiperSlide>
<img src="https://swiperjs.com/demos/images/nature-4.jpg" />
</SwiperSlide>
<SwiperSlide>
<img src="https://swiperjs.com/demos/images/nature-5.jpg" />
</SwiperSlide>
<SwiperSlide>
<img src="https://swiperjs.com/demos/images/nature-6.jpg" />
</SwiperSlide>
<SwiperSlide>
<img src="https://swiperjs.com/demos/images/nature-7.jpg" />
</SwiperSlide>
<SwiperSlide>
<img src="https://swiperjs.com/demos/images/nature-8.jpg" />
</SwiperSlide>
<SwiperSlide>
<img src="https://swiperjs.com/demos/images/nature-9.jpg" />
</SwiperSlide>
<SwiperSlide>
<img src="https://swiperjs.com/demos/images/nature-10.jpg" />
</SwiperSlide>
</Swiper>
</>
);
}
export default App;

Is it working in react?
What about next js?

use this
<BrowserRouter>
<App />
</BrowserRouter>
instead of
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>

This is the final solution for this problem
import React, { useLayoutEffect, useRef, useState } from "react";
import { Swiper, SwiperSlide } from "swiper/react";
import "swiper/css";
import "swiper/css/free-mode";
import "swiper/css/navigation";
import "swiper/css/thumbs";
import SwiperClass from "swiper/types/swiper-class";
import SwiperCore, { FreeMode, Navigation, Thumbs, Controller } from "swiper";
export default function AdSwiper() {
const [thumbsSwiper, setThumbsSwiper] = useState<SwiperCore>();
const [firstSwiper, setFirstSwiper] = useState<SwiperClass>();
const [secondSwiper, setSecondSwiper] = useState<SwiperClass>();
const swiper1Ref = useRef<React.MutableRefObject<null>>(null);
const swiper2Ref = useRef();
useLayoutEffect(() => {
if (swiper1Ref.current !== null) {
swiper1Ref.current.controller.control = swiper2Ref.current;
}
}, []);
return (
<div className="h-[550px] ">
<Swiper
onSwiper={(swiper) => {
if (swiper1Ref.current !== null) {
swiper1Ref.current = swiper;
}
}}
preloadImages={false}
controller={{ control: secondSwiper }}
spaceBetween={10}
slidesPerView={1}
grabCursor={true}
navigation={true}
thumbs={{
swiper: thumbsSwiper && !thumbsSwiper.destroyed ? thumbsSwiper : null,
}}
modules={[FreeMode, Navigation, Thumbs, Controller]}
className="w-[848px] h-[454px] rounded-xl"
>
<SwiperSlide>
<img src="https://a.d-cd.net/9634e6s-960.jpg" />
</SwiperSlide>
<SwiperSlide>
<img src="https://a.d-cd.net/a5634e6s-960.jpg" />
</SwiperSlide>
<SwiperSlide>
<img src="https://a.d-cd.net/13634e6s-960.jpg" />
</SwiperSlide>
<SwiperSlide>
<img src="https://a.d-cd.net/e3634e6s-960.jpg" />
</SwiperSlide>
<SwiperSlide>
<img src="http://carsot.com/images/daewoo-nubira-ii-1999-2003-sedan-interior-2.jpg" />
</SwiperSlide>
<SwiperSlide>
<img src="https://www.4tuning.ro/images/elemente-caroserie-din-dezmembrari-daewoo-nubira/elemente-caroserie-din-dezmembrari-daewoo-nubira-8fd6c1475ef586f2cf-1100-615-2-85-1.jpg" />
</SwiperSlide>
<SwiperSlide>
<img src="https://a.d-cd.net/5283186s-480.jpg" className="w-full" />
</SwiperSlide>
<SwiperSlide>
<img src="https://a.d-cd.net/JCAAAgGDAuA-960.jpg" />
</SwiperSlide>
<SwiperSlide>
<img src="https://a.d-cd.net/a5634e6s-960.jpg" />
</SwiperSlide>
</Swiper>
<Swiper
controller={{ control: firstSwiper }}
loop={false}
spaceBetween={10}
slidesPerView={8}
watchSlidesProgress
touchRatio={0.2}
preloadImages={false}
lazy
slideToClickedSlide={true}
onSwiper={setThumbsSwiper}
modules={[Navigation, Thumbs, Controller]}
className="h-[100.4px] w-[848px] mt-[20px] rounded-xl"
>
<SwiperSlide className="w-[70px]">
<img
src="https://a.d-cd.net/9634e6s-960.jpg"
className=" rounded-xl h-[70px]"
/>
</SwiperSlide>
<SwiperSlide className="w-[70px]">
<img
src="https://a.d-cd.net/a5634e6s-960.jpg"
className=" rounded-xl h-[70px]"
/>
</SwiperSlide>
<SwiperSlide className="w-[70px]">
<img
src="https://a.d-cd.net/13634e6s-960.jpg"
className=" rounded-xl h-[70px]"
/>
</SwiperSlide>
<SwiperSlide className="w-[70px]">
<img
src="https://a.d-cd.net/e3634e6s-960.jpg"
className=" rounded-xl h-[70px]"
/>
</SwiperSlide>
<SwiperSlide className="w-[70px]">
<img
src="http://carsot.com/images/daewoo-nubira-ii-1999-2003-sedan-interior-2.jpg"
className=" rounded-xl h-[70px]"
/>
</SwiperSlide>
<SwiperSlide className="w-[70px]">
<img
className=" rounded-xl h-[70px]"
src="https://www.4tuning.ro/images/elemente-caroserie-din-dezmembrari-daewoo-nubira/elemente-caroserie-din-dezmembrari-daewoo-nubira-8fd6c1475ef586f2cf-1100-615-2-85-1.jpg"
/>
</SwiperSlide>
<SwiperSlide className="w-[70px]">
<img
className=" rounded-xl h-[70px]"
src="https://a.d-cd.net/5283186s-480.jpg"
/>
</SwiperSlide>
<SwiperSlide className="w-[70px]">
<img
className=" rounded-xl h-[70px]"
src="https://a.d-cd.net/JCAAAgGDAuA-960.jpg"
/>
</SwiperSlide>
<SwiperSlide className="w-[70px]">
<img
src="https://a.d-cd.net/a5634e6s-960.jpg"
className=" rounded-xl h-[70px]"
/>
</SwiperSlide>
</Swiper>
</div>
);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

Related

How do I make dynamic routing work in Vue?

I got a project and when I use :to, my dynamic routes dont work..I also can't seem to pass params. The buttons supposed to be used as dynamic routes are declared in the v-for loop. I am using Quasar CLI / Vue3.
It'd be really awesome if some of you had an insight as to why this does not work. I get no errors, simply, when I hover over the button it shows no url as it normally would in a browser.
The view displaying items:
<template>
<div class="projects">
<div class="text-h3 project-title">
Favourite Projects <q-icon name="star" color="yellow" />
</div>
</div>
<div class="project-container">
<div class="q-pa-md project-card">
<q-card class="my-card single-projects no-shadow no-border-radius">
<q-img
src="https://res.cloudinary.com/practicaldev/image/fetch/s--9yBkqrjS--/c_imagga_scale,f_auto,fl_progressive,h_500,q_auto,w_1000/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nphrgz8yfnjylrwfr0yl.png"
>
<div class="absolute-bottom">
<div class="text-h6">
Damn good project
<q-icon name="star" color="yellow" />
</div>
<div class="text-subtitle2">by Big Boi</div>
</div>
</q-img>
<q-card-actions class="project-btns">
<q-btn
unelevated
size="md"
class="open-btn no-border-radius dropdown-btn"
>Open</q-btn
>
<q-btn
flat
no-caps
unelevated
size="md"
class="delete-btn no-border-radius"
color="red"
#click="confirm = true"
>Delete</q-btn
>
<q-dialog v-model="confirm" persistent class="dialog no-shadow">
<q-card>
<q-card-section class="row items-center">
<span class="q-ml-sm"
>Are you sure you want to delete this project?</span
>
</q-card-section>
<q-card-actions align="center">
<q-btn
flat
no-caps
label="Cancel"
color="black"
class="no-border-radius"
v-close-popup
/>
<q-btn
flat
no-caps
label="Delete"
color="red"
class="no-border-radius"
v-close-popup
/>
</q-card-actions>
</q-card>
</q-dialog>
</q-card-actions>
</q-card>
</div>
</div>
<div class="projects">
<div class="text-h3 project-title">All Projects</div>
</div>
<div v-for="item in items" :key="item.project" class="project-container">
<div class="q-pa-md project-card">
<q-card class="my-card single-projects no-shadow no-border-radius">
<q-img
src="https://res.cloudinary.com/practicaldev/image/fetch/s--9yBkqrjS--/c_imagga_scale,f_auto,fl_progressive,h_500,q_auto,w_1000/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nphrgz8yfnjylrwfr0yl.png"
>
<div class="absolute-bottom">
<div class="text-h6">{{ item.project }}</div>
<div class="text-subtitle2">by {{ item.author }}</div>
</div>
</q-img>
<q-card-actions class="project-btns">
<q-btn
:to="{
name: 'project',
params: {
project: item.project,
},
}"
unelevated
size="md"
class="open-btn no-border-radius dropdown-btn"
>Open
</q-btn>
<q-btn
flat
no-caps
unelevated
size="md"
class="delete-btn no-border-radius"
color="red"
#click="confirm = true"
>Delete</q-btn
>
<q-dialog v-model="confirm" persistent class="dialog no-shadow">
<q-card>
<q-card-section class="row items-center">
<span class="q-ml-sm"
>Are you sure you want to delete this project?</span
>
</q-card-section>
<q-card-actions align="center">
<q-btn
flat
no-caps
label="Cancel"
color="black"
class="no-border-radius"
v-close-popup
/>
<q-btn
flat
no-caps
label="Delete"
color="red"
class="no-border-radius"
v-close-popup
/>
</q-card-actions>
</q-card>
</q-dialog>
</q-card-actions>
</q-card>
</div>
</div>
</template>
<script lang="ts">
import { ref } from 'vue';
export default {
name: 'myProjects',
setup() {
return {
confirm: ref(false),
items: [
{ project: 'good project', id: '302a49g8Aa43', author: 'Josh' },
{ project: 'okay fine', id: '65at9g847a11', author: 'Tray' },
{ project: 'let me see', id: '538s3fg4782f', author: 'Martin' },
],
};
},
};
</script>
This is also my router where I do the routing:
{
path: '/project/:id',
props: true,
component: () => import('layouts/SingleProLayout.vue'),
children: [{ path: '', component: () => import('pages/Project.vue') }],
},
Try wrapping the q-btn inside a router-link https://router.vuejs.org/api/

How to update radio-buttons group based on selection

I have a working on a Responsive yes/no questionnaire where user can select either yes/no on each of the posed questions.
I want each questionCard component to have a radio-button group (yes/no). The radio-circles should be hidden and only label should be visible. Clicking on the label should select the appropiate option.
ALL THIS WORKS
My issue comes in when I re-size the window! The layout changes appropietly but the radio selection is gone.
Any Ideas how I can keep the selection regardless the window size?
CodeSandbox
App.vue
<template>
<parent-component />
</template>
<script>
import parentComponent from "./components/parentComponent.vue";
export default {
name: "App",
components: {
parentComponent,
},
};
</script>
<style>
</style>
Parent.vue
<template>
<div>
<question-card
v-for="car in objectData.cars.data"
:key="car.id"
:carData="car"
></question-card>
</div>
</template>
<script>
import questionCard from "./questionCard.vue";
export default {
name: "App",
components: {
questionCard,
},
data() {
return {
objectData: {
cars: {
data: [
{
id: 1,
name: "Do You Like Tesla?",
},
{
id: 2,
name: "Do You Like BMW?",
},
{
id: 3,
name: "Do You Like AUDI?",
},
],
},
},
};
},
};
</script>
Questioncard.vue
<template>
<br />
<br />
<div class="hidden sm:block">
<h1>Lage Screen</h1>
<h2 class="font-bold">{{ carData.name }}</h2>
<div class="flex items-center justify-center">
<input
#change="onChange($event)"
type="radio"
:name="carData.id"
:id="carData.id + 'yes'"
/>
<label
:for="carData.id + 'yes'"
class="border text-center border-yellow-500 rounded-2xl w-11/12 py-0.5 hover:bg-red-500 hover:text-white hover:border-green-300"
>
<span>Yes</span>
</label>
</div>
<div class="flex items-center justify-center">
<input
#change="onChange($event)"
type="radio"
:name="carData.id"
:id="carData.id + 'no'"
/>
<label
:for="carData.id + 'no'"
class="border text-center border-yellow-500 rounded-2xl w-11/12 py-0.5 hover:bg-red-500 hover:text-white hover:border-green-300"
>
<span>No</span>
</label>
</div>
</div>
<div class="sm:hidden">
<h1>Small Screen</h1>
<h2 class="font-bold">{{ carData.name }}</h2>
<div class="flex items-center w-1/2 justify-center">
<input
#change="onChange($event)"
type="radio"
:name="carData.id"
:id="carData.id + 'yes'"
/>
<label
:for="carData.id + 'yes'"
class="border text-center border-yellow-500 rounded-2xl w-11/12 py-0.5 hover:bg-red-500 hover:text-white hover:border-green-300"
>
<span>Yes</span>
</label>
</div>
<div class="flex items-center w-1/2 justify-center">
<input
#change="onChange($event)"
type="radio"
:name="carData.id"
:id="carData.id + 'no'"
/>
<label
:for="carData.id + 'no'"
class="border text-center border-yellow-500 rounded-2xl w-11/12 py-0.5 hover:bg-red-500 hover:text-white hover:border-green-300"
>
<span>No</span>
</label>
</div>
</div>
</template>
<script>
export default {
props: ["carData"],
data() {
return {
selected: null,
};
},
methods: {
onChange(event) {
this.selected = event.target.value;
},
},
};
</script>
<style scoped>
input[type="radio"] {
display: none;
}
input[type="radio"]:checked + label {
background-color: #78be20;
}
</style>
I see you are using TailwindCSS. You can control the sizes with w-1/2 sm:w-full on the elements
You don't need different input for the different screen sizes. Like this
<div class="">
<h1>Any size Screen</h1>
<h2 class="font-bold">{{ carData.name }}</h2>
<div class="flex items-center justify-center w-1/2 sm:w-full">
<input
#change="onChange($event)"
type="radio"
:name="carData.id"
:id="carData.id + 'yes'"
/>
<label
:for="carData.id + 'yes'"
class="border text-center border-yellow-500 rounded-2xl w-11/12 py-0.5 hover:bg-red-500 hover:text-white hover:border-green-300"
>
<span>Yes</span>
</label>
</div>
<div class="flex items-center justify-center w-1/2 sm:w-full">
<input
#change="onChange($event)"
type="radio"
:name="carData.id"
:id="carData.id + 'no'"
/>
<label
:for="carData.id + 'no'"
class="border text-center border-yellow-500 rounded-2xl w-11/12 py-0.5 hover:bg-red-500 hover:text-white hover:border-green-300"
>
<span>No</span>
</label>
</div>
</div>

TinyMce breaking TailwindCss animation when loaded inside a slide-over element

I have a simple Vue3 application that is making heavy use of TailwindUI components. I'm trying to place a TinyMce editor inside of a slide over component and that works fine. The issue is the entry animation.
On first entry, it slides in like it's supposed to. However, if it is closed and reopened the entry animation is gone. The whole time the exit animation continues to work without issue. Is there a way I can do this and keep the animation intact?
Here is a CodeSandBox with the issue reproduced in it's simplest form.
Here is the relevant code:
App.vue
<template>
<button #click="open = true">Open Menu</button>
<SlideOver :open="open" #close="open = false" />
</template>
<script>
import { ref } from "vue";
import SlideOver from "./components/slide-over.vue";
export default {
name: "App",
components: {
SlideOver,
},
setup() {
const open = ref(false);
return { open };
},
};
</script>
slide-over.vue
<!-- This example requires Tailwind CSS v2.0+ -->
<template>
<TransitionRoot as="template" :show="open">
<Dialog
as="div"
static
class="fixed inset-0 overflow-hidden"
#close="$emit('close')"
:open="open"
>
<div class="absolute inset-0 overflow-hidden">
<DialogOverlay class="absolute inset-0" />
<div class="fixed inset-y-0 right-0 pl-10 max-w-full flex">
<TransitionChild
as="template"
enter="transform transition ease-in-out duration-500 sm:duration-700"
enter-from="translate-x-full"
enter-to="translate-x-0"
leave="transform transition ease-in-out duration-500 sm:duration-700"
leave-from="translate-x-0"
leave-to="translate-x-full"
>
<div class="w-screen max-w-md">
<div
class="h-full flex flex-col py-6 bg-white shadow-xl overflow-y-scroll"
>
<div class="px-4 sm:px-6">
<div class="flex items-start justify-between">
<DialogTitle class="text-lg font-medium text-gray-900">
Panel title
</DialogTitle>
<div class="ml-3 h-7 flex items-center">
<button
class="bg-white rounded-md text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
#click="$emit('close')"
>
<span class="sr-only">Close panel</span>
<XIcon class="h-6 w-6" aria-hidden="true" />
</button>
</div>
</div>
</div>
<div class="mt-6 relative flex-1 px-4 sm:px-6">
<TinyMceEditor api-key="no-api-key" />
</div>
</div>
</div>
</TransitionChild>
</div>
</div>
</Dialog>
</TransitionRoot>
</template>
<script>
import {
Dialog,
DialogOverlay,
DialogTitle,
TransitionChild,
TransitionRoot,
} from "#headlessui/vue";
import { XIcon } from "#heroicons/vue/outline";
import TinyMceEditor from "#tinymce/tinymce-vue";
export default {
components: {
Dialog,
DialogOverlay,
DialogTitle,
TransitionChild,
TransitionRoot,
XIcon,
TinyMceEditor,
},
props: {
open: {
type: Boolean,
default: false,
},
},
setup() {},
};
</script>
In my opinion, this is a problem with loading the TinyMce Editor (I don't know exactly what the problem is). I added a delay in loading the editor after opening the modal using watchEffect based on the props open with setTimeout in it and v-if on the TinyMceEditor tag. It may not be a perfect and aesthetic solution, but the animation works smoothly.
Here is a code in codesandbox.io.
And code here: slide-over.vue (App.vue stays the same)
<template>
<TransitionRoot as="template" :show="open">
<Dialog
as="div"
static
class="fixed inset-0 overflow-hidden"
#close="$emit('close')"
:open="open"
>
<div class="absolute inset-0 overflow-hidden">
<DialogOverlay class="absolute inset-0" />
<div class="fixed inset-y-0 right-0 pl-10 max-w-full flex">
<TransitionChild
as="template"
enter="transform transition ease-in-out duration-500 sm:duration-700"
enter-from="translate-x-full"
enter-to="translate-x-0"
leave="transform transition ease-in-out duration-500 sm:duration-700"
leave-from="translate-x-0"
leave-to="translate-x-full"
>
<div class="w-screen max-w-md">
<div
class="h-full flex flex-col py-6 bg-white shadow-xl overflow-y-scroll"
>
<div class="px-4 sm:px-6">
<div class="flex items-start justify-between">
<DialogTitle class="text-lg font-medium text-gray-900">
Panel title
</DialogTitle>
<div class="ml-3 h-7 flex items-center">
<button
class="bg-white rounded-md text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
#click="$emit('close')"
>
<span class="sr-only">Close panel</span>
<XIcon class="h-6 w-6" aria-hidden="true" />
</button>
</div>
</div>
</div>
<div class="mt-6 relative flex-1 px-4 sm:px-6">
<TinyMceEditor v-if="loadEditor" api-key="no-api-key" />
</div>
</div>
</div>
</TransitionChild>
</div>
</div>
</Dialog>
</TransitionRoot>
</template>
<script>
import { ref, watchEffect } from "vue";
import {
Dialog,
DialogOverlay,
DialogTitle,
TransitionChild,
TransitionRoot,
} from "#headlessui/vue";
import { XIcon } from "#heroicons/vue/outline";
import TinyMceEditor from "#tinymce/tinymce-vue";
export default {
components: {
Dialog,
DialogOverlay,
DialogTitle,
TransitionChild,
TransitionRoot,
XIcon,
TinyMceEditor,
},
props: {
open: {
type: Boolean,
default: false,
},
},
setup(props) {
const loadEditor = ref(false);
watchEffect(() => {
if (props.open) {
setTimeout(function () {
loadEditor.value = true;
}, 10);
} else {
loadEditor.value = false;
}
});
return { loadEditor };
}
};
</script>

Looping a new <q-item> with <q-popoup-edit> nested doesn't work in quasar framework

I have been searching for solution for my problem, but still not resolved :')..
Anyway, Thanks so much for the help, Masters :)
So,
I have a button for add new task with this code inside the q-item-section , but when I clicked it, it is not adding new item as a expected..
<q-btn
#click="addMore"
class="text-weight-bolder"
label="Add"
size="14px"
color="white"
flat
icon-right="mdi-plus-circle-outline"
/>
By clicking above button, it will shows a new item (by using following code below), which is needed to be filled by users
<q-item v-for="task in todoOthers2" :key="task">
<q-item-section avatar>
<div class="cursor-pointer size-16px">
{{ task.time }}
<q-popup-edit v-model="time" class="bg-grey-2 text-white" :cover="false" :offset="[0, 10]" v-slot="scope">
<q-input filled v-model="todoOthers2.time" mask="time" :rules="['time']">
<template v-slot:append>
<q-icon name="access_time" class="cursor-pointer text-primary">
<q-popup-proxy transition-show="scale" transition-hide="scale">
<q-time v-model="time">
<div class="row items-center justify-end">
<q-btn v-close-popup label="Close" color="primary" flat />
</div>
</q-time>
</q-popup-proxy>
</q-icon>
</template>
</q-input>
</q-popup-edit>
</div>
</q-item-section>
<q-item-section no-wrap >
<div class="cursor-pointer text-weight-bolder" style="width: 100px">
{{task.activity}}
<q-popup-edit v-model="todoOthers2.activity" class="bg-grey-2 text-white" :cover="false" :offset="[0, 10]" v-slot="scope">
<q-input v-model="scope.value" dense autofocus counter #keyup.enter="scope.set">
<template v-slot:append>
<q-icon name="edit" />
</template>
</q-input>
</q-popup-edit>
</div>
</q-item-section>
<q-item-section top side>
<div class="text-grey-8 q-gutter-xs">
<q-btn size="12px" color="secondary" flat dense round icon="mdi-check-circle" />
<q-btn size="12px" color="negative" flat dense round icon="mdi-delete" />
</div>
</q-item-section>
</q-item>
Here is the setup()
setup() {
const todoOthers2 = ref({
activity:"Add Your Task Here",
time:"08:00"
function addMore(){
todoOthers2.value.push({
activity: "Add Your Task Here",
time:"08:00"
})
return {
todoOthers2,
addMore,
}
}

How to render a modal that is inside a component from another component in vueJs and Bootstrap

I have a modal inside a Vue component. Now, from another component i want to show that modal(component) when an event happens(click in a button).
This is the code of the component(modal)
This is the component where i want to get the modal
Code of the component with the modal
<template>
<div class="modal fade" id="exampleModal" tabindex="" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modificar Registro Documento</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="false">×</span>
</button>
</div>
<div class="modal-body">
</div>
<div class="modal-footer">
<button data-dismiss="modal" (click)="modificarRegistro()" type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
</template>
<script lang="ts" scoped>
export default {
name : "Modal"
}
</script>
<style lang="sass" scoped>
</style>
This is the code of the component where i want to get the modal
<template>
<div id="contenedor">
<div id="padre">
<div id="barra">
<Modal/>
<div v-if="producto === 'bebidas'" class="tabcontent">
<div>
<button v-on:click="modal()" data-toggle="modal" data-target="#exampleModal">
<h6>Inka Kola</h6>
<img src="../../assets/incakolaPersonal.jpg" />
</button>
</div>
<div>
<button>
<h6>Coca Kola</h6>
<img src="../../assets/cocaKolaPersona.png" />
</button>
</div>
<div>
<button>
<h6>Sprite</h6>
<img src="../../assets/sprite.webp" />
</button>
</div>
<div>
<button>
<h6>Cielo</h6>
<img src="../../assets/cieloPersonal.webp" />
</button>
</div>
<div>
<button>
<h6>San Mateo</h6>
<img src="../../assets/sanmateoPersonal.webp" />
</button>
</div>
<div>
<button>
<h6>Ruskalla</h6>
<img src="../../assets/ruskalla.webp" />
</button>
</div>
<div>
<button>
<h6>Ron</h6>
<img src="../../assets/ron.webp" />
</button>
</div>
<div>
<button>
<h6>Cristal</h6>
<img src="../../assets/cristal.jpg" />
</button>
</div>
</div>
<div v-if="producto === 'carnes'" class="tabcontent">
<div>
<button>
<h6>Pollo</h6>
<img src="../../assets/pollo.jpg" />
</button>
</div>
<div>
<button>
<h6>Carne</h6>
<img src="../../assets/carne.jpg" />
</button>
</div>
<div>
<button>
<h6>Cerdo</h6>
<img src="../../assets/cerdo.jpg" />
</button>
</div>
</div>
<div v-if="producto === 'tuberculos'" class="tabcontent">
<div>
<button>
<h6>Papa</h6>
<img src="../../assets/papa.jpg" />
</button>
</div>
<div>
<button>
<h6>Yuca</h6>
<img src="../../assets/yuca.jpg" />
</button>
</div>
<div>
<button>
<h6>Olluco</h6>
<img src="../../assets/olluco.webp" />
</button>
</div>
<div>
<button>
<h6>Jengibre</h6>
<img src="../../assets/jengibre.jpg" />
</button>
</div>
</div>
</div>
</div>
</template>
<style lang="sass" scoped>
#contenedor
display: flex
justify-content: center
#padre
width: 100%
display: flex
flex-direction: column
justify-content: center
#barra
margin-top: 40px
display: flex
button
border-radius: 0px
.tabcontent
background-color: #999999
display: flex
flex-wrap: wrap
justify-content: space-around
width: 100%
height: 100%
div
margin: 20px
flex-grow: 1
button
border: 0px
img
width: 100px
height: 120px
</style>
<script>
import Modal from "./Modal";
export default {
name: "Barra",
data: function () {
return {
producto: "bebidas",
modalEstado : false
};
},
methods: {
mostrar: function (a) {
this.producto = a;
},
modal(){
this.modalEstado=true;
console.log(this.modalEstado);
}
},
};
</script>