Nuxt Props pass to data and set images - vue.js

how do i pass props into data ? i have a object that pass into prop and i want prop to set the image url with data "mainImage", must keep the mainImage.
<template>
<!-- start Product Header -->
<div class="ps-product__header">
<div class="ps-product__thumbnail" data-vertical="false">
<div class="ps-wrapper">
<div class="ps-product__gallery">
<div class="col-12 px-md-2 d-none d-md-block">
<div class="" style="cursor: pointer">
<b-img :src="mainImage" alt="" style="width: 100%" class="image" #click="showMainImage()"></b-img>
</div>
</div>
</div>
</div>
<div class="ps-product__variants">
<div class="col-12 d-none d-md-block my-4">
<div class="row">
<div class="col-3" v-for="(image, index) in product.images" :key="index">
<div class="thumbnail" style="cursor: pointer" #click="changeMainImage(image.src)">
<b-img :src="`${image.src}`" style="width: 100%" alt="" class="image" :class="mainImage === image ? 'activess' : ''"></b-img>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
here is the script
<script>
export default {
name: 'ShopHeader',
props: {
product: {
type: Object,
required: true
}
},
data() {
return {
mainImage: String,
}
},
methods: {
changeMainImage(image) {
this.mainImage = image
}
},
mounted() {
this.mainImage = this.product.image
console.log(this.mainImage)
}
}
</script>
sample : https://stackblitz.com/edit/nuxt-starter-pake3o?file=components%2FShopHeader.vue
when you type on the stackblitz url with /product, the image will show up but when you go through the link the image wont show up, so anyone know how to fix this problem ? i assume it was mounted only load once and component wont render after it.

add v-if to tag
<img v-if="mainImage" :src="mainImage" class="image">

Related

How to toggle between components when onclick function happens on a icon in vue.js?

I have four components Dashboard.vue(parent component) it contains Three child components(DisplayBooks.vue,sortBooksHightoLow,sortBooksLowtoHigh).
Now i want to import one more component called Cart.vue inside the Dashboard.vue .By default only DisplayBooks.vue component is only visible,if i click on cart-icon inside the Dashboard component it displays the Cart.vue component and hides the DisplayBooks.vue component .
How to acheive this thing please help me to fix this thing..
Dashboard.vue
<template>
<div class="main">
<div class="navbar navbar-default navbar-fixed-top">
<div class="navbar-header">
<img src="../assets/education.png" alt="notFound" class="education-image" />
</div>
<ul class="nav navbar-nav">
<li>
<p class="brand">Bookstore</p>
</li>
</ul>
<div class="input-group">
<i #click="handlesubmit();" class="fas fa-search"></i>
<div class="form-outline">
<input type="search" v-model="name" class="form-control" placeholder='search...' />
</div>
</div>
<ul class="nav navbar-nav navbar-right" id="right-bar">
<li><a> <i class="far fa-user"></i></a></li>
<p class="profile-content">profile</p>
<li><a><i class="fas fa-cart-plus"></i></a></li>
<p class="cart-content" >cart <span class="length" v-if="booksCount">{{booksCount}}</span></p>
</ul>
</div>
<div class="mid-body">
<h6>Books<span class="items">(128items)</span></h6>
<select class="options" #change="applyOption">
<option disabled value="">Sort by relevance</option>
<option value="HighToLow">price:High to Low</option>
<option value="LowToHigh">price:Low to High</option>
</select>
</div>
<div v-if="flam==false">
<h2>Hello</h2>
</div>
<DisplayBooks v-show="flag==='noOrder'" #update-books-count="(n)=>booksCount=n"/>
<sortBooksLowtoHigh v-show="flag==='lowToHigh'" />
<sortBooksHightoLow v-show="flag==='highToLow'" />
<Cart />
</div>
</template>
<script>
import sortBooksLowtoHigh from './sortBooksLowtoHigh.vue'
import sortBooksHightoLow from './sortBooksHightoLow.vue'
import DisplayBooks from './DisplayBooks.vue'
import Cart from './Cart.vue'
export default {
components: {
DisplayBooks,
sortBooksLowtoHigh,
sortBooksHightoLow,
Cart
},
data() {
return {
booksCount:0,
flag: 'noOrder',
brand: 'Bookstore',
name: '',
flam: true,
visible: true,
}
},
methods: {
flip() {
this.flam = !this.flam;
},
applyOption(evt) {
if (evt.target.value === "HighToLow") {
this.flag = 'highToLow';
} else this.flag = 'lowToHigh';
},
}
}
</script>
Cart.vue
<template>
<div class="main">
<div v-for="book in books" :key="book.id" class="container">
<div class="content">
<h5>My Cart({{booksCount}})</h5>
</div>
<div class="mid-section">
<img v-bind:src="book.file" alt="not found">
<p class="title-section">{{book.name}}</p>
</div>
<div class="author-section">
<p>by {{book.author}}</p>
</div>
<div class="price-section">
<h6>Rs.{{book.price}}</h6>
</div>
<button class="close-btn" #click="handlesubmit();" type="submit">close</button>
<div class="btn-grps">
<button class="btn" type="submit" >Place Order</button>
</div>
</div>
</div>
</template>
<script>
import service from '../service/User'
export default{
data(){
return {
booksCount:0,
books: [{
id: 0,
file: 'https://images-na.ssl-images-amazon.com/images/I/41MdP5Tn0wL._SX258_BO1,204,203,200_.jpg',
name: 'Dont Make me think',
author: 'Sai',
price: '1500'
},]
}
},
methods:{
}
}
</script>
It's recommended to use vur-router, but for a simple situation you could define a property called shownComp then update when you click on cart icon :
data() {
return {
shownComp:'DisplayBooks',
booksCount:0,
flag: 'noOrder',
then <li #click="shownComp='Cart'"><a><i class="fas fa-cart-plus"></i></a></li>
and :
<DisplayBooks v-show="flag==='noOrder' && shownComp==='DisplayBooks'" #update-books-count="(n)=>booksCount=n"/>
<Cart v-show=" shownComp==='Cart'" />
...

Bind data with router-link in the vue

I have declared a data variable inside my component. There is a select box that dynamically changes this data value. what I want to use this data value inside my router-link. but somehow it is not working.
Here is my code for the same:
<template>
<div class="row bg-blue content-padding pdt-70 relative d-flex">
<div class="col-md-8">
<div class="row mgb-60">
<form>
<div class="col-8 form-group mgb-30">
<label for="work-profile" class="color-white">Work Profile*</label>
<select id="work-profile" v-model="page" name="work-profile" class="form-control">
<option value="self-employed">Self Employed</option>
<option value="salaried">Salaried</option>
</select>
</div>
<div class="col-12 form-group">
<router-link :to=["/"+page]>
<button type="submit" class="btn form-button button-blue d-flex-inline justify-content-center align-items-center color-white bg-blue">Get Started</button>
</router-link>
</div>
</form>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "LandingPage",
data: function()
{
return{
page:'salaried'
}
},
components: {
},
};
</script>
Replace <router-link :to=["/"+page]> to <router-link :to="'/'+page"> you do not need [] with binding to

Vue: Data 'undefind' when component render

I would like to set a class to one of my elements when current language I equal to element id. But when method is fired to do this check then I have log "undefined".
Why? How to set that class properly?
Is data object loaded latter then component render?
<template>
<div>
<div class="star-box">
<div class="head">
<img :src="'images/flags/en.png'"
id="en"
class="student-img"
v-bind:class="{'activeLanguage': checkActiveLanguage('en')}"
alt=""
>
</div>
<div class="body">
<h5 class="heading">English</h5>
</div>
</div>
<div class="star-box">
<div class="head">
<img :src="'images/flags/de.png'"
id="de"
class="student-img"
v-bind:class="{'activeLanguage': checkActiveLanguage('de')}"
alt=""
>
</div>
<div class="body">
<h5 class="heading">Deutsch</h5>
</div>
</div>
</div>
</template>
JS
<script>
import {mapActions,mapGetters} from 'vuex';
export default {
name: 'Language',
data() {
return {
language: ''
}
},
methods: {
checkActiveLanguage: (lang)=> {
console.log(this.language);
if(lang==this.language) return true;
},
...mapGetters(['getCurrentLanguage']),
},
beforeMount(){
this.language = this.getCurrentLanguage();
}
}
</script>

render vuejs bindes in v-html from string

i'm generete this html for a chatbubble depending on a api call response. the html gets added to a local var. it shows by using <div v-html="messages">/<div> in the components template.
this only works when i call this.$forceUpdate(); after the html is added.
problem: there is a button
'<a v-on:click="askdialogflow" >'+classes["first"]+'</a>'
this works and renders when it's added directly to the template. when it renders from a string, it does not convert it.
problem: v-html does not render/compile the button
hardcoded call:
this.Questionclasses({first: "10010300", second: "02170705", third: "03070403", fourth: "18110000"});
Code:
<template>
<div class='chat-wrapper' id="chat-wrapper">
<div v-html = "messages" ></div>
</div>
</template>
<script>
import axios from 'axios';
export default {
name: 'App',
data: {
messages:"",
imageData: "" // we will store base64 format of image in this string
},
methods: {
checkImage() {
this.imageData =localStorage["image"]
axios.post('http://localhost:5000/api/start',{img:localStorage["image"].split(",")[1]})
.then(response =>{
this.Questionclasses(JSON.parse(response.data));
})
.catch(e => {
this.errors.push(e)
})
},
startBlock(){
let html = ` <div class='chat-message chat-message-sender'>
<img class='chat-image chat-image-default' src='./../../static/user.jpg' />
<div class='chat-message-wrapper'>
<div class='chat-message-content'>
<img class="startImage" src="` + this.imageData +`">
<p>Analyseer deze foto alstublieft.</p>
</div>
<div class='chat-details'>
<span class='chat-message-localisation font-size-small'>Time</span>
</div>
</div>
</div>`
this.messages = html;
},
Questionclasses(classes){
let html =` <div class='chat-message padding'>
<div class='chat-message chat-message-recipient'>
<img class='chat-image chat-image-default' src='./../../static/tvh_robot-pro.png' />
<div class='chat-message-wrapper'>
<div class='chat-message-content'>
<div class="classImage-wrapper">
<div>
<p>
<img src="./../../static/kip.jpg" class="classImage">
</p>
<p> <a v-on:click="askdialogflow" >`+classes["first"]+`</a> </p>
</div>
<div>
<p>
<img src="./../../static/kip.jpg" class="classImage">
</p>
<p><a>`+classes["second"]+`</a></p>
</div>
<div>
<p>
<img src="./../../static/kip.jpg" class="classImage">
</p>
<p><a>`+classes["third"]+`</a> </p>
</div>
<div>
<p>
<img src="./../../static/kip.jpg" class="classImage">
</p>
<p><a>`+classes["fourth"]+`</a> </p>
</div>
</div>
<p>geen van bovenstaande</p>
</div>
<div class='chat-details'>
<span class='chat-message-localization font-size-small'>Time</span>
</div>
</div>
</div>
</div>
`
console.log(html)
this.messages += html;
this.$forceUpdate();
},
askdialogflow(event){
console.log(event)
}
},
beforeMount(){
this.checkImage();
this.startBlock();
},
}
</script>

How can I open a bootstrap modal while another modal is active in vue.js component?

I have 3 vue components
My first component (MultiplePhoto.vue):
<template>
<div>
<table class="table table-bordered table-thumb">
<tr>
<template v-for="item in items">
<td data-target="#modal-option" data-toggle="modal">
...
</td>
</template>
<option-modal id="modal-option" :product="product"></option-modal>
</tr>
</table>
</div>
</template>
<script>
import OptionModal from './OptionModal.vue'
export default {
name: 'MultiplePhoto',
props: ['product'],
components: { OptionModal },
data() {
return {
items: [1,2,3,4,5]
}
},
...
}
</script>
If I click the td tag it successfully displays modal (OptionModal component)
My second component (OptionModal.vue):
<template>
<div class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-body">
<div class="form-horizontal">
<div class="form-group">
<div class="col-sm-9">
<a data-target="#modal-edit-photo" data-toggle="modal">Edit</a>
</div>
</div>
...
</div>
</div>
</div>
</div>
<edit-image-modal id="modal-edit-photo" :id-product="product.id"></edit-image-modal>
</div>
</template>
<script>
import EditImageModal from './EditImageModal.vue'
export default{
name: 'OptionModal',
props: ['product'],
components: { EditImageModal},
....
}
</script>
In OptionModal component, if I click the a tag, it tagdoesn't display the modal (EditImageModal component)
My third component (EditImageModal.vue):
<template>
<div class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
....
</div>
</div>
</div>
</template>
<script>
export default {
name: 'EditImageModal',
,,,
}
</script>
There is no error.and I'm still confused how to solve the problem.
How can I solve the problem?
Please help me