Change element background-image inside a v-for - vue.js

I have a v-for thats reading different .md files which have a image property in their front matter.
I am trying to change my div's background-image But it has to read that url taken from the files frontmatter.
this is the code:
<div v-for="item in projectsList" class="li" >
<div style="background-image: url(https://i.pinimg.com/originals/4f/c4/92/4fc49228a940e41435b3796c18fc2346.jpg)">
<a :href="item.path" class="li">
<span>{{ item.title }}</span>
</a>
</div>
</div>
Now the issue lies in changing the style:"background-image: url(<URL>) property.
I can access the image through item.frontmatter.image,
I read about this so i tried to do an example and just for testing purposes tried to feed an image through the Data function, but to vue the Url is undefined so i need a different way of feeding a URL based image to the background.
:style:"{'background-image': url( imageURL )}"
data: function () {
return {
imageURL: 'https://i.pinimg.com/originals/4f/c4/92/4fc49228a940e41435b3796c18fc2346.jpg'
}
},

You should be able to do it like this:
<div v-for="item in projectsList" class="li" >
<div :style="{ 'background-image': `url(${item.frontmatter.image})` }">
<a :href="item.path" class="li">
<span>{{ item.title }}</span>
</a>
</div>
</div>
No data function needed here I think.

Related

Nuxt.js/Vue.js dynamic images is not working

I'm getting some data from an API that contains an image and some other information. Now there's a problem in Nuxt js or maybe I'm wrong. Whenever I supply the path to the image in the :src it just doesn't work.
Here's my code:
<div v-for="(project, index) in projects" :key="project.p_id" class="swiper-slide">
<div :id="`index_${index}`" class="slide_wrapper">
<div class="background">
<img :src="getImgUrl(project.p_img_path)" alt="project cover image" />
</div>
<div class="details">
<div>
<div class="left">
<h2 style="color: black !impor tant">{{ project.p_label }}</h2>
<small>{{ project.p_date }}</small>
</div>
<div class="right">
<nuxt-link class="btn btn-secondary" to="/" #click="readMore">
<i class="fas fa-ellipsis-h"></i>
</nuxt-link>
</div>
</div>
</div>
</div>
</div>
script:
props: ['projects'],
methods: {
readMore() {},
getImgUrl(path) {
return '../../../' + path
},
},
Last thing, whenever I use required required('./assets/'+image.jpg') nuxt.js crushes in compilation always stops at 69%. I also tried required.context but it didn't work as well.
Any help will be appreciated. Thanks in advance.
In your template, change:
<img :src="getImgUrl(project.p_img_path)" alt="project cover image">
To:
<img :src="require(`../assets/${project.p_img_path}`)" alt="project cover image">
You shouldn’t need a method to return the path as a string, just use a template literal as above.
Ps. This assumes project.p_img_path = img/project_img/filename.jpg, so adjust as necessary.
The solution is that I had to put all the images inside the assets folder directly. Thank you all for your time.

v-on:click not working - dynamically added html element

I am trying to get all images for a category using Vue
<div class="col-md-12 col-sm-2 p-2">
<a v-on:click="onCategoryManageImageClick($event)" data-target="#location-
category-images">
</span>
</a>
</div>
So the event onCategoryManageImageClick ($event) does not work, if I am adding a html block and then click on get image button.
this is index.js
methods:{
onImagesTabClick(){
this.$root.$emit('activated-tab:location-images');
},
onCategoriesTabClick(){
window.j1App.eventBus.$emit("j1-location-image-list:shown");
},
onCategoryManageImageClick: function(event) {console.log('working event..');
event.preventDefault();
window.j1App.eventBus.$emit("j1-location-category-image-
list:shown",event.currentTarget.id);
}
}
So basically it need to to work like we do in jQuery
$(document).on('click',function{
})
So it works either page load or if adding any new html element on DOM. same I want in Vue.
You cannot alter the Vue template outside of Vue. That won't work. Vue compiles the template once when starting up and adds the event listeners to the rendered elements. If you add elements afterwards, Vue will not know about them.
The correct way of doing this would be to add those new elements in Vue.
<div
class="col-md-12 col-sm-2 p-2"
v-for="item in items"
:key="item.id"
>
<a
v-on:click="onCategoryManageImageClick($event, item)"
data-target="#location-category-images"
>
</a>
</div>
See https://v2.vuejs.org/v2/guide/list.html for documentation. In this case you need the items array variable in data and add more array elements to it, if you need more links.
Try raplacing your a tag with p
<div class="col-md-12 col-sm-2 p-2">
<p v-on:click="onCategoryManageImageClick" data-target="#location-
category-images">
</p>
</div>

Show Div When Hover Based on ID in Vue JS

I have a div that when i want hover to it, it will show other div. However, my first div is dynamic, it has an ID. So how will i able to hover to ID based on its ID?
It should be #mouseenter="hoverService{{services.id}} = true" but it causes error. So i made the code below to just static.
Here's my code below:
<template>
<div
class="col-md-3"
v-for="(services, index) in servicesFiltered"
:key="index"
#mouseenter="hoverService = true"
#mouseleave="hoverService = false"
>
<div class="service_background" v-if="hoverService">
<div class="mb-1" v-for="(sub_services, index) in services.menu_items" :key="index">
<router-link
:to="{ path: `/${sub_services.data}`}"
>
<a
href="#"
class="btn btn-outline-primary w-100 services_button"
>{{sub_services.text }}</a>
</router-link>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
hoverService: false
};
}
};
</script>
Try this code
https://codesandbox.io/s/y7p9qyyovz
You need to maintain hover for each item you can not manipulate using single variable for multiple items.

overwrite bootstrap css rules not working, css files and rules seen but properties ignored

I use bootswatch v3.3.6 and django 1.11.2
I want to make a button full width inside a bootstrap's table column, but something very peculiar happens as can be seen in the following pictures:
I want to make that blue button full width. I have added a btn-buy class to my template and the corresponding css:
.btn-buy.btn-primary {
"width": 100%;
}
The problem is that width property is ignored as the red arrow points. However if I click on store.css :
and write on the firebug console the property:
then the modification is applied correctly:
No matter how I write the class btn-buy or e.g if I make it an id instead, the result is the same.
This is the relevant DTL code:
<div class="col-lg-3 col-md-4 col-xs-6 thumb">
<div id="plan-thumb" class="thumbnail">
<h3>Name</h3>
<hr>
<h4 align="center">{{ plan.description }}</h4>
<ul>
<li>Calls per minute: {{ plan.requests_per_minute }}</li>
<li>Calls per day: {{ plan.requests_per_day }}</li>
<li>Calls per minute: {{ plan.requests_per_month }}</li>
</ul>
<h5 class="pull-middle">Price per month: {{ plan.price }}$</h5>
<hr>
<div class="bottom-align-text">
{# todo this should be JS instead of new url, pushing a popup of terms etc #}
<button type="button" class=" btn-buy btn-primary" href="#"> Buy
{# href="{% url 'store:buy' plan_id=plan.id %}"> #}
</button>
</div>
</div> {# end of thumbnail div #}
</div>
Any ideas on why my modifications are not being applied automatically?

How to access V-for elements

I have Large Image elements dynamically rendered using v-for
<div class="preview-pic tab-content">
<div class="tab-pane"
v-bind:class="activeClass"
:id= index
v-for="(imgLink, index) in itemSelected.itemImages"
v-bind:ref="index">
<img :src="imgLink.urlLargeImage" />
</div>
</div>
I also have Thumbnail images rendered in v-for
<li v-for="(imgLink, index) in itemSelected.itemImages">
<a #click="onImgClicked" :data-target="'#' + index" data-toggle="tab">
<img :src="imgLink.urlThumbnail" />
</a>
</li>
in my methods:
methods:{
onImgClicked: function (index) {
document.getElementById(index).className="active" // works but is it vue-way?
this.$refs.0.className = "active" // only works if i know what index of the thumbnail will be clicked
}
}
When a thumbnail image is clicked, I'd like to make it's corresponding large image to be active by setting the css class "active". I can accomplish this with document.getelementbyid, but is that the vue-way? My attempt with $refs
I also attempted using v-bind but I was unsuccessful because either all large images will be active or not active.
If you only want one image active at a time, add an activeImage property to your data.
data(){
return {
activeImage: null
}
}
Modify your template in this way.
<div class="preview-pic tab-content">
<div class="tab-pane"
:class="{active: imgLink === activeImage}"
:id= index
v-for="(imgLink, index) in itemSelected.itemImages"
v-bind:ref="index">
<img :src="imgLink.urlLargeImage" />
</div>
</div>
...
<li v-for="(imgLink, index) in itemSelected.itemImages">
<a #click="activeImage = imgLink"
:data-target="'#' + index" data-toggle="tab">
<img :src="imgLink.urlThumbnail" />
</a>
</li>
And get rid of your onImgClicked. Also, you will want to set activeImage to null when you don't want any image active.
Alternatively, if more than one image could be active at a time, add a boolean active property to your imgLink objects, and change your template to
:class="{active: imgLink.active}"
and
#click="imgLink.active = !imgLink.active"