How to check different id (ref) for using one method in Vue JS - vue.js

I am new in Vue. In my code I gonna use a lot of same looking container and all of them should have slider page. For now when I clicking on top of container all slider-pages is coming out. I am understand,I should add id(ref) to each container. But I still cant get how to use it. Huge Thanks for any help or advice.
<template>
<div #click="shotList" ref="123">
<span>
<div
class="d-flex flex-row top-row justify-content-center mt-5"
style="z-index: 111 !important"
>
<div class="flex-row d-flex top-size">
<span class="col text-left" style="margin-top: -2px"
>21:40-23:00</span
>
<span class="col-9 text-right" style="margin-top: -2px"
>UFC 256 MMA</span
>
</div>
</div>
<div
class="d-flex flex-row justify-content-center"
style="z-index: 111 !important"
>
<div class="flex-row d-flex bottom-size">
<span class="col-5 bottom-size-white">Habib</span>
<span class="col-2 bottom-size-green"
>5%
<p class="bottom-p">Volatility</p>
</span>
<span class="col-5 bottom-size-black">Connor</span>
</div>
</div>
</span>
<ListBase :title="[{ text: `3`, value: `2` }]" />
</div>
<div #click="shotList" ref="125">
<span>
<div
class="d-flex flex-row top-row justify-content-center mt-5"
style="z-index: 111 !important"
>
<div class="flex-row d-flex top-size">
<span class="col text-left" style="margin-top: -2px"
>21:40-23:00</span
>
<span class="col-9 text-right" style="margin-top: -2px"
>UFC 256 MMA</span
>
</div>
</div>
<div
class="d-flex flex-row justify-content-center"
style="z-index: 111 !important"
>
<div class="flex-row d-flex bottom-size">
<span class="col-5 bottom-size-white">Habib</span>
<span class="col-2 bottom-size-green"
>5%
<p class="bottom-p">Volatility</p>
</span>
<span class="col-5 bottom-size-black">Connor</span>
</div>
</div>
</span>
<ListBase :title="[{ text: `3`, value: `2` }]" />
</div>
</template>
<script>
export default {
name: "take",
data() {
return {
show: false,
};
},
methods: {
shotList() {
this.show = !this.show;
if (this.show) {
this.$emit("openList");
} else {
this.$emit("closeList");
}
},
spaceCheck(event) {
let x = event.pageX;
let y = event.pageY;
console.log(x, y);
},
},
};
</script>

Related

VueJS reusable component not updated data for second component

I am trying to create one component in VueJS and need to reuse that component.
below is code for me.
Vue.component("radio" , {
props: ['selectGender'],
data: function() {
return{
selected: 1
}
},
template : `
<div class="modal fade" :id="compId" style="background: rgb(0, 0, 0, 0.8);">
<div class="modal-dialog default-font" style="top: 30%;">
<div class="modal-content center">
<div class="modal-header base-bg center">
<div class="center">
<span class="validationHeadSpan">Select Gender</span><br/>
</div>
<button type="button" class="close modal-close" data-dismiss="modal" style="font-size:3rem">×</button>
</div>
<div class="modal-body t-left" id="printArea">
<div class="container">
<div class="row" style="padding: 0rem 1rem;">
<div class="col">
<div class="custom-control custom-radio" style="margin: 1rem 0rem;">
<input class="custom-control-input" type="radio" id="rdbMale" value="0" checked v-model="selected"/>
<label class="custom-control-label" for="rdbMale">
<div class="addr_header_1" style="margin-top: 0.8rem;">Male</div>
</label>
</div>
</div>
<div class="col">
<div class="custom-control custom-radio" style="margin: 1rem 0rem;">
<input class="custom-control-input" type="radio" id="rdbFemale" value="0" checked v-model="selected"/>
<label class="custom-control-label" for="rdbFemale">
<div class="addr_header_1" style="margin-top: 0.8rem;">Female</div>
</label>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer center">
<button type="button" class="button" data-dismiss="modal" v-on:click="selectGender(selected)"><span class="validationButtonContent">Select</span></button>
</div>
</div>
</div>
</div>
`,
mounted : function(){
},
methods : {
}
});
Here is my another component from where i am opening reusable component.
Vue.component("Component1" , {
data: function() {
return{
selected: 1
}
},
template : `
<div>
<radio ref="returnOpenFirst" :selectGender="selectGenderFirst"></radio>
<radio ref="returnOpenSecond" :selectGender="selectGenderSecond"></radio>
</div>
<div class="btn btn-primary formButton" v-on:click="openFirst">
<span>Open First</span>
</div>
<div class="btn btn-primary formButton" v-on:click="openSecond">
<span>Open First</span>
</div>
`,
mounted : function(){
},
methods : {
openFirst:function(){
jQuery(self.$refs.returnOpenFirst.$el).modal({
'backdrop' : false
}).modal('show');
},
openSecond:function(){
jQuery(self.$refs.returnOpenSecond.$el).modal({
'backdrop' : false
}).modal('show');
},
selectGenderFirst:function(gender){
console.log("First Gender", gender);
},
selectGenderSecond:function(gender){
console.log("Second Gender", gender);
},
}
});
While opening second component, data property is updated of first component only not for second component.
Any help is highly appreciated.
Thanks in advance.
Here i found solution.
Vue.component("radio" , {
props: ['selectGender','type'],
data: function() {
return{
selected: 1
}
},
template : `
<div class="modal fade" :id="compId" style="background: rgb(0, 0, 0, 0.8);">
<div class="modal-dialog default-font" style="top: 30%;">
<div class="modal-content center">
<div class="modal-header base-bg center">
<div class="center">
<span class="validationHeadSpan">Select Gender</span><br/>
</div>
<button type="button" class="close modal-close" data-dismiss="modal" style="font-size:3rem">×</button>
</div>
<div class="modal-body t-left" id="printArea">
<div class="container">
<div class="row" style="padding: 0rem 1rem;">
<div class="col">
<div class="custom-control custom-radio" style="margin: 1rem 0rem;">
<input class="custom-control-input" type="radio" :id="'rdbMale'+type" value="0" checked v-model="selected"/>
<label class="custom-control-label" :for="'rdbMale'+type">
<div class="addr_header_1" style="margin-top: 0.8rem;">Male</div>
</label>
</div>
</div>
<div class="col">
<div class="custom-control custom-radio" style="margin: 1rem 0rem;">
<input class="custom-control-input" type="radio" :id="'rdbFemale'+type" value="0" checked v-model="selected"/>
<label class="custom-control-label" :for="'rdbFemale'+type">
<div class="addr_header_1" style="margin-top: 0.8rem;">Female</div>
</label>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer center">
<button type="button" class="button" data-dismiss="modal" v-on:click="selectGender(selected)"><span class="validationButtonContent">Select</span></button>
</div>
</div>
</div>
</div>
`,
mounted : function(){
},
methods : {
}
});
Issue with same id created by VueJs, we need to pass one dynamic property and with the use of that we need to create id for radio.
Thank you guys.

After obtaining more data the open panel is not correct

When loading the panels the first time and opening the panel in the third position. Everything is Ok.
When loading more elements, the panel that opens is not correct but it is still the one in the third position.
<div id="load-conversation">
<div class="row" style="margin-bottom: 10px;" v-show="referencesList.length >0">
<div class="col-md-12 text-center">
<button v-on:click="getEmails" class="btn btn-sm btn-blue">Cargar más</button>
</div>
</div>
<div class="panel panel-info" v-for="email in emails">
<!-- Head Panel-->
<div class="panel-heading" v-bind:class=" email.incoming ? 'white-inbox' : 'blue-reply'"
data-toggle="collapse" :href="`#collapse-new${email.id}`">
<!--Email Title-Button -->
<div class="row">
<div class="col-md-8">
<h5 v-if="email.incoming"><span class="fas fa-reply" aria-hidden="true"></span> ${email.sender_name}</h5>
<h5 v-else><span class="fas fa-share-square" aria-hidden="true"></span> ${email.sender_name}</h5>
</div>
</div>
</div>
<!--Body Panel-->
<div :id="`collapse-new${email.id}`" class="panel-collapse collapse">
<div class="panel-body">
<!--Email Head-->
<div class="container-fluid">
<div class="row">
<strong>SUBJECT: </strong><span class="text-info">${email.subject}</span></br>
<strong>FROM: </strong><span class="text-info">${email.sender_email}</span></br>
<strong>TO: </strong><span class="text-info"><span v-for="to in email.to">${to.email}, </span></span></br>
<strong>DATE: </strong><span class="text-info">${email.date}</span></br>
<strong v-if="email.cc.length > 0">CC: </strong><span class="text-info"><span v-for="cc in email.cc">${cc.email}, </span></span>
</div>
</div>
<br>
<!--Email Body-->
<div class="row container-fluid">
<div class="list-group-item"v-html="email.content_html">
</div>
<div>
<div class="bs-component">
<ul class="pager">
<li class="previous" data-toggle="collapse" :data-target="`#open-details-new${email.id}`">
<a href="javascript:void(0)">
<span class="glyphicon glyphicon-option-horizontal" aria-hidden="true"></span>
</a>
</li>
</ul>
</div>
<div :id="`open-details-new${email.id}`" class="collapse" v-html="email.complete_html">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
The important thing is to see that the new elements are placed in the order of the old elements, that is, the order is reversed in the list. By only adding the elements without changing the order everything works correctly.
<script>
var loadMore = new Vue({
el: '#load-conversation',
delimiters: ['${', '}'],
data: {
limit : 3,
referencesList : [1,2,3,4,5],
emails : [],
showLoadBtn: true,
},
mounted() {
this.getEmails()
},
methods: {
getEmails(){
axios.post("get_more_emails", { references: this.getReferences() })
.then(response => {
//console.log(response.data);
this.emails = [ ...response.data, ...this.emails ]
}).catch(function (error) {
console.log('error', error)
});
},
getReferences(){
...
}
},
})
</script>

b-table render all the data without respecting the fields

I am building a project using laravel and Vue JS to create a list of companies with pagination etc..
I am using bootstrap-table and the problem the table render all the data without respecting the fields that I am giving as a param. I want to use scope field to show a custom css inside every row. I use the same table with other data it works fine.
This is the component code
<template>
<div class="row">
<div class="col-lg-3 mt-lg-5">
<div class="card bord-rad-5">
<div class="card-header purple-background top-borders">
<h4
class="title-align font-montserrat text-light white-text-color mt-3 position-filter"
>
Filter
</h4>
</div>
<div class="card-body">
<div class="d-flex flex-column">
<div
class="gray-text-color font-weight-bold font-montserrat-regular mb-2"
>
<h5>{{ $t('labels.frontend.filters.companyName') }}</h5>
</div>
<div class="form-group">
<b-form-group class="ml-1">
<b-input-group>
<b-form-input v-model="filter" placeholder="Type to search">
</b-form-input>
<b-input-group class="mr-2">
<b-button
class="mr-left-90 mr-4 mt-2 font-montserrat-regular"
:disabled="!filter"
#click="filter = ''"
>
{{ $t('labels.frontend.companies.clear') }}
</b-button>
</b-input-group>
</b-input-group>
</b-form-group>
</div>
<div
class="gray-text-color font-weight-bold font-montserrat-regular mt-2 mb-2"
>
<h5>{{ $t('labels.frontend.filters.companyType') }}</h5>
</div>
<div class="form-check form-check-inline mt-1 mb-1">
<input
class="form-check-input"
type="checkbox"
id="ac1"
value="AssemblyCompany"
/>
<label
class="form-check-label gray-text-color font-weight-bold font-montserrat-thin"
for="ac1"
>
{{ $t('labels.frontend.filters.dismantling') }}
</label>
</div>
<div class="form-check form-check-inline mt-1 mb-1">
<input
class="form-check-input"
type="checkbox"
id="gd1"
value="garagebusiness"
/>
<label
class="form-check-label gray-text-color font-weight-bold font-montserrat-thin"
for="gd1"
>
{{ $t('labels.frontend.filters.garage') }}
</label>
</div>
<div class="form-check form-check-inline mt-1 mb-1">
<input
class="form-check-input"
type="checkbox"
id="rb1"
value="RevisionCompany"
/>
<label
class="form-check-label gray-text-color font-weight-bold font-montserrat-thin"
for="rb1"
>
{{ $t('labels.frontend.filters.revision') }}
</label>
</div>
</div>
</div>
</div>
</div>
<div class="mt-5 col-lg-9">
<div class="card-header purple-background bord-top-lr-5">
<b-row class="mt-2">
<b-col>
<h4 class="title-align font-montserrat text-light white-text-color">
{{ items.count }} {{ $t('labels.frontend.companies.results') }}
</h4>
</b-col>
<b-form-group label-cols-sm="3" class="mb-2 w-25 mr-4">
<b-form-select v-model="perPage" :options="pageOptions">
</b-form-select>
</b-form-group>
</b-row>
</div>
<div class="card-body white-bg">
<div class="grid-x grid-padding-x m-2 border-0">
<div class="border-0 mb-2">
<b-table
striped
hover
:items="items.data"
:fields="columns"
:filter="filter"
:current-page="currentPage"
:per-page="perPage"
:outlined="outlined"
responsive
>
<template slot="name" class="m-3" slot-scope="item">
<h5 class="title-align font-montserrat" style="color: #5b2557">
<a :href="data.item.url" :title="data.item.name">
{{ data.item.name }}
</a>
</h5>
<div class="row">
<div class="col">
<p
class="gray-text-color font-montserrat-thin font-weight-bold"
>
{{ data.item.street }}
{{ data.item.building_nr }} {{ data.item.postal }}
{{ data.item.city }} {{ data.item.state }}
</p>
</div>
<div class="col ml-lg-5">
<p
class="font-montserrat-thin blue-light-color font-weight-bold"
>
T. {{ data.item.phone }}<br />
<a
:href="data.item.website"
target="_blank"
:title="data.item.name"
class="gray-text-color"
>
{{ $t('labels.frontend.companies.goTo') }}
</a>
</p>
</div>
<div class="col ml-lg-5">
<a
class="font-montserrat-regular"
:href="
$app.route('frontend.companies.show', data.item.slug)
"
style="color: #74aee0"
>
{{ $t('labels.frontend.companies.moreInfo') }} »
</a>
</div>
</div>
<button
class="mb-3 blue-light-bg btn bord-rad-5 white-text-color font-montserrat-regular"
href="#"
>
{{ $t('labels.frontend.companies.stock') }}
</button>
<br />
</template>
</b-table>
<b-row>
<b-col md="6" class="my-1">
<b-pagination
v-model="currentPage"
:total-rows="totalRows"
:per-page="perPage"
class="my-0"
></b-pagination>
</b-col>
</b-row>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'SearchCompaniesTable',
props: {
companyName: {
type: String,
required: false,
default: () => ''
}
},
data() {
return {
filter: null,
totalRows: 1,
currentPage: 1,
perPage: 10,
pageOptions: [5, 10, 25],
outlined: true,
columns: [
{
field: 'name',
label: 'Name'
}
],
items: []
}
},
computed: {
rows() {
return Object.keys(this.items).length
}
},
mounted() {
axios.get('/companies/search').then(response => {
this.items = response.data
this.totalRows = this.items.count
console.log(this.fields)
})
}
}
</script>
<style>
.hidden_header {
display: none;
}
thead {
border: none !important;
}
tbody {
border: none !important;
border-color: white;
}
table {
border: none !important;
}
th {
border: none !important;
}
tr {
border: none !important;
}
td {
border: none !important;
}
.mr-left-90 {
margin-left: 68px;
}
.position-filter {
position: relative;
top: -8px;
}
</style>
could you please help me to find a solution for that ?
Here you can find the code for the component
<template>
<div class="row">
<div class="col-lg-3 mt-lg-5">
<div class="card bord-rad-5">
<div class="card-header purple-background top-borders">
<h4
class="title-align font-montserrat text-light white-text-color mt-3 position-filter"
>
Filter
</h4>
</div>
<div class="card-body">
<div class="d-flex flex-column">
<div
class="gray-text-color font-weight-bold font-montserrat-regular mb-2"
>
<h5>{{ $t('labels.frontend.filters.companyName') }}</h5>
</div>
<div class="form-group">
<b-form-group class="ml-1">
<b-input-group>
<b-form-input v-model="filter" placeholder="Type to search">
</b-form-input>
<b-input-group class="mr-2">
<b-button
class="mr-left-90 mr-4 mt-2 font-montserrat-regular"
:disabled="!filter"
#click="filter = ''"
>
{{ $t('labels.frontend.companies.clear') }}
</b-button>
</b-input-group>
</b-input-group>
</b-form-group>
</div>
<div
class="gray-text-color font-weight-bold font-montserrat-regular mt-2 mb-2"
>
<h5>{{ $t('labels.frontend.filters.companyType') }}</h5>
</div>
<div class="form-check form-check-inline mt-1 mb-1">
<input
class="form-check-input"
type="checkbox"
id="ac1"
value="AssemblyCompany"
/>
<label
class="form-check-label gray-text-color font-weight-bold font-montserrat-thin"
for="ac1"
>
{{ $t('labels.frontend.filters.dismantling') }}
</label>
</div>
<div class="form-check form-check-inline mt-1 mb-1">
<input
class="form-check-input"
type="checkbox"
id="gd1"
value="garagebusiness"
/>
<label
class="form-check-label gray-text-color font-weight-bold font-montserrat-thin"
for="gd1"
>
{{ $t('labels.frontend.filters.garage') }}
</label>
</div>
<div class="form-check form-check-inline mt-1 mb-1">
<input
class="form-check-input"
type="checkbox"
id="rb1"
value="RevisionCompany"
/>
<label
class="form-check-label gray-text-color font-weight-bold font-montserrat-thin"
for="rb1"
>
{{ $t('labels.frontend.filters.revision') }}
</label>
</div>
</div>
</div>
</div>
</div>
<div class="mt-5 col-lg-9">
<div class="card-header purple-background bord-top-lr-5">
<b-row class="mt-2">
<b-col>
<h4 class="title-align font-montserrat text-light white-text-color">
{{ items.count }} {{ $t('labels.frontend.companies.results') }}
</h4>
</b-col>
<b-form-group label-cols-sm="3" class="mb-2 w-25 mr-4">
<b-form-select v-model="perPage" :options="pageOptions">
</b-form-select>
</b-form-group>
</b-row>
</div>
<div class="card-body white-bg">
<div class="grid-x grid-padding-x m-2 border-0">
<div class="border-0 mb-2">
<b-table
striped
hover
:items="items.data"
:fields="columns"
:filter="filter"
:current-page="currentPage"
:per-page="perPage"
:outlined="outlined"
responsive
>
<template slot="name" class="m-3" slot-scope="item">
<h5 class="title-align font-montserrat" style="color: #5b2557">
<a :href="data.item.url" :title="data.item.name">
{{ data.item.name }}
</a>
</h5>
<div class="row">
<div class="col">
<p
class="gray-text-color font-montserrat-thin font-weight-bold"
>
{{ data.item.street }}
{{ data.item.building_nr }} {{ data.item.postal }}
{{ data.item.city }} {{ data.item.state }}
</p>
</div>
<div class="col ml-lg-5">
<p
class="font-montserrat-thin blue-light-color font-weight-bold"
>
T. {{ data.item.phone }}<br />
<a
:href="data.item.website"
target="_blank"
:title="data.item.name"
class="gray-text-color"
>
{{ $t('labels.frontend.companies.goTo') }}
</a>
</p>
</div>
<div class="col ml-lg-5">
<a
class="font-montserrat-regular"
:href="
$app.route('frontend.companies.show', data.item.slug)
"
style="color: #74aee0"
>
{{ $t('labels.frontend.companies.moreInfo') }} »
</a>
</div>
</div>
<button
class="mb-3 blue-light-bg btn bord-rad-5 white-text-color font-montserrat-regular"
href="#"
>
{{ $t('labels.frontend.companies.stock') }}
</button>
<br />
</template>
</b-table>
<b-row>
<b-col md="6" class="my-1">
<b-pagination
v-model="currentPage"
:total-rows="totalRows"
:per-page="perPage"
class="my-0"
></b-pagination>
</b-col>
</b-row>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'SearchCompaniesTable',
props: {
companyName: {
type: String,
required: false,
default: () => ''
}
},
data() {
return {
filter: null,
totalRows: 1,
currentPage: 1,
perPage: 10,
pageOptions: [5, 10, 25],
outlined: true,
columns: [
{
field: 'name',
label: 'Name'
}
],
items: []
}
},
computed: {
rows() {
return Object.keys(this.items).length
}
},
mounted() {
axios.get('/companies/search').then(response => {
this.items = response.data
this.totalRows = this.items.count
console.log(this.fields)
})
}
}
</script>
What mistake i am doing and thank you for answering
In your first code snippet your style is not using the scoped attribute, which may mean the rest of your project is doing he same thing. This could mean that your CSS is being overwritten at the global level, If you inspect the element after render can you see if your CSS is being overwritten somewhere.
Also, if you happen to be using SCSS the bootstrap-vue library supports it very well and I have found it to be easier to adjust the bootstrap css easier.
I fixed the problem by changing the code inside the template tag from <template slot="name" slot-scope="item"> to <template v-slot:cell(name)="data">

How to add vue #click event in tooltip title content?

I will need to add #click event handler to the tooltip content. so the user can click on the tooltip to get more details.
simply writing #click will not work.
Vue full Calendar code here I use the eventRender event to attach the tooltips.
<FullCalendar
ref="fullCalendar"
:customButtons="this.customButtons"
:eventLimit="this.config.eventLimit"
:header="false"
:events="events"
:plugins="calendarPlugins"
:defaultDate="date"
#datesRender="setDatepickerValue"
#eventRender="getEventDetailsPopup"
defaultView="dayGridMonth"
/>
and the event rendered event handler code mentioned below
methods: {
getEventDetailsPopup: function(mouseInfo) {
var tooltip = new Tooltip(mouseInfo.el, {
title: `
<div class="container max-w-sm mx-auto overlay cursor-pointer rounded">
<div class="centered flex items-center m-4 w-full ">
<div class="w-1/3 h-12 ">
<i class="fa fa-heart" aria-hidden="true"></i>
<span class="text-white">0</span>
</div>
<div class="w-1/3 h-12">
<i class="fa fa-comment" aria-hidden="true"></i>
<span class="text-white">0</span>
</div>
<div class="w-1/3 h-12">
<i class="fa fa-retweet" aria-hidden="true"></i>
<span class="text-white">0</span>
</div>
<div class="w-1/3 h-12 ">
<i class="fa fa-location-arrow" aria-hidden="true"></i>
<span class="text-white">0</span>
</div>
</div>
</div>
<div class="container bg-white max-w-1 mx-auto">
<div class="max-w-sm rounded overflow-hidden shadow-lg">
<img
class="w-full h-32"
src="https://tailwindcss.com/img/card-top.jpg"
alt="Sunset in the mountains"
>
<div class="px-6 py-4 ">
<div class="font-bold text-xl mb-2">${mouseInfo.event.title}</div>
<p class="text-gray-700 text-base">
${mouseInfo.event.extendedProps.description}
</p>
</div>
<div class="px-6 py-2 bg-blue-900 h-9">
<span class="inline-block bg-gray-200 rounded-full px-3 text-sm font-semibold text-gray-700 mr-2">
Autoschedule</span>
</div>
</div>
</div>`,
placement: "right",
trigger: "hover",
html: true,
container: "body",
delay: { show: 100 },
template: `<div class="tooltip calendar" role="tooltip">
<div class="tooltip-arrow x-arrow"></div>
<div class="tooltip-inner"></div>
</div>`
});
},
callEventDetailPopup: function() {
console.log("called");
},
Need to add a click handler on the title content.
try this
<FullCalendar #eventClick="eventClick" />

Is there a way to get the data from multiple selects as array?

I'm currently stuck on a task on VueJS. Basically I'm trying to create an array from multiple select inside a form to get all the data as an array or Object to process it further. I just searched but got no results or an idea on how to solve my issue.
Parent Component
<template>
<div id="product" class="mt-12">
<div class="flex flex-wrap mb-4">
<div class="w-1/2 pr-12">
<img src="https://placehold.it/800" alt="">
</div>
<div class="w-1/2">
<div class="flex justify-between content-center h-12 mb-4">
<div class="text-gray-700 py-2">
<h2 v-if="product.brand" class="leading-none font-bold text-sm">{{ product.brand }}</h2>
<h1 class="text-xl leading-snug">{{ product.name }}</h1>
</div>
<div class="text-gray-700 py-2">
<p class="text-xl font-bold leading-none">{{ product.price }}</p>
<p class="text-xs text-right leading-none">Inkl. 19% MwSt.</p>
</div>
</div>
<div class="divider bg-gray-400 mt-4 mb-4" />
<div id="variations">
<form action="">
<ProductVariation v-for="(variations, type) in product.variations" :type="type" :variations="variations" :key="type" v-model="form.variation"/>
<div class="flex w-full">
<button class="w-full leading-none bg-blue-500 hover:bg-blue-600 text-white py-2 rounded" type="submit">Add to cart</button>
</div>
</form>
</div>
</div>
</div>
</div>
</template>
<script>
import ProductVariation from '#/components/products/ProductVariation'
export default {
data () {
return {
product: null,
form: {
variation: null
}
}
},
components: {
ProductVariation
},
async asyncData({ params, app }) {
let response = await app.$axios.$get(`products/${params.slug}`)
return {
product: response.data
}
}
}
</script>
ProductVariation Component
<template>
<div class="flex mb-4">
<div class="w-full">
<label class="block text-gray-700 w-full text-sm font-bold">{{ type }}</label>
<select class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight" :name="type">
<option value="0">Please select</option>
<option v-for="variation in variations" :key="variation.id" :value="variation.id">{{ variation.name }} <span>( +{{ variation.price }} )</span></option>
</select>
</div>
</div>
</template>
<script>
export default {
props: {
type: {
required: true,
type: String
},
variations: {
required: true,
type: Array
}
},
}
</script>