export default {
name: 'MovieSlider',
data() {
return {
index: 0,
imgs: [
'https://7themes.su/_ph/40/303277371.jpg',
'https://7themes.su/_ph/23/730607462.jpg',
'https://7themes.su/_ph/23/730607462.jpg',
],
};
},
computed: {
sideSlide() {
return {
transform: `translateX(${-this.index * 100}vw)`,
};
},
},
methods: {},
left() {
this.index++;
if (this.index > this.imgs.length - 1) {
this.index = 0;
}
this.sideSlide;
},
right() {
this.index--;
if (this.index < 0) {
this.index = this.imgs.length - 1;
}
this.sideSlide;
},
};
<template>
<div class="carusel">
<div class="image-container imgs">
<button class="left buttons" #click="left">
<i class="fa-solid fa-angle-left"></i>
</button>
<div v-for="item in imgs" :key="item.id" :style="sideSlide">
<img :src="item" />
</div>
<button class="right buttons" #click="right">
<i class="fa-solid fa-chevron-right"></i>
</button>
</div>
<div class="popular_films">
<div class="content">
<p class="film_name">Film Name</p>
<p class="film_info">
<i class="fa-solid fa-star"></i>
<span>FIlm vote</span>
<span>Film time</span>
<span>Film year</span>
</p>
<span class="play_treiler"
>Trailer<i class="fa-solid fa-play"></i
></span>
</div>
</div>
</div>
</template>
Hi friends, I want to make slider with vue but something is going wrong, after pressing right or left i want to give a style(size) to image that slides to another image but something is going wrong, in here you can find all of the code that i used in this component, Thank you.
Related
I am using vue chevron in accordion inside for loop. When I am clicking a single dropdown, all other chevrons are rotating. How to rotate the specific chevron for the clicked dropdown in vue ? I am using vue chevron package from https://ispal.github.io/vue-chevron/ . My dropdown looks like this -
My vue code:
<div class="accordion" id="accordionExample">
<div
v-for="(data, index) in topicList"
:key="index"
class="card"
>
<div class="card_header" id="headingOne">
<h2 class="mb-0">
<div
class="btn btn-topic example text-left collapsed"
#click="toggle"
type="button"
data-toggle="collapse"
:data-target="'#collapseOne' + index"
aria-expanded="true"
aria-controls="collapseOne"
>
<vue-chevron
:point-down="pointDown"
:duration="duration"
:thickness="thickness"
:angle="angle"
:round-edges="roundEdges"
/>
{{ data.title }}
</div>
</h2>
</div>
<div
:id="'collapseOne' + index"
class="collapse"
aria-labelledby="headingOne"
data-parent="#accordionExample"
>
<div class="card-body">
<ul
v-for="(data, index) in topicList[index].lessons"
:key="index"
#click="getContent(data.lessonId)"
class="list-group py-1"
>
<li class="list-group-item list-style">
{{ data.title }}
</li>
</ul>
</div>
</div>
</div>
</div>
<script>
import VueChevron from "vue-chevron"
export default{
components:{ VueChevron }
data(){
return{
pointDown: false,
thickness: 8,
duration: 500,
angle: 40,
roundEdges: true,
easing: function n(t) {
return t;
}
}
methods: {
toggle() {
this.pointDown = !this.pointDown;
},
}
}
courseAccess() {
this.$axios
.get(this.$api + "api/v1/courses/" + this.courseId, {
headers: {
Authorization: "Bearer " + localStorage.getItem("_utoken"),
},
})
.then((response) => {
// this.topicList = response.data.data.topics.map((element) => {
// return { ...element, pointDown: true };
// });
this.topicList = response.data.data.topics
this.firstTopic = response.data.data.topics[0].lessons[0].lessonId;
this.getFirstContent(this.firstTopic);
this.loadTopics = true;
});
},
All vue-chevron are binding there point-down prop to the same boolean. You could try to use an array of boolean instead and change your toggle method.
<div class="accordion" id="accordionExample">
<div
v-for="(data, index) in topicList"
:key="index"
class="card"
>
<div class="card_header" id="headingOne">
<h2 class="mb-0">
<div
class="btn btn-topic example text-left collapsed"
#click="toggle(index)"
type="button"
data-toggle="collapse"
:data-target="'#collapseOne' + index"
aria-expanded="true"
aria-controls="collapseOne"
>
<vue-chevron
:point-down="pointDown[index]"
:duration="duration"
:thickness="thickness"
:angle="angle"
:round-edges="roundEdges"
/>
{{ data.title }}
</div>
</h2>
</div>
<div
:id="'collapseOne' + index"
class="collapse"
aria-labelledby="headingOne"
data-parent="#accordionExample"
>
<div class="card-body">
<ul
v-for="(data, index) in topicList[index].lessons"
:key="index"
#click="getContent(data.lessonId)"
class="list-group py-1"
>
<li class="list-group-item list-style">
{{ data.title }}
</li>
</ul>
</div>
</div>
</div>
</div>
<script>
import VueChevron from "vue-chevron"
export default{
components:{ VueChevron }
data(){
return{
pointDown: [],
thickness: 8,
duration: 500,
angle: 40,
roundEdges: true,
easing: function n(t) {
return t;
}
}
methods: {
toggle(index) {
this.pointDown[index] = !this.pointDown[index];
},
}
}
EDIT
The problem discussed in the comments could be caused by reactivity issues. To solve these we are trying to initialize pointDown with an array of the correct size.
courseAccess() {
this.$axios
.get(this.$api + "api/v1/courses/" + this.courseId, {
headers: {
Authorization: "Bearer " + localStorage.getItem("_utoken"),
},
})
.then((response) => {
// this.topicList = response.data.data.topics.map((element) => {
// return { ...element, pointDown: true };
// });
this.topicList = response.data.data.topics;
this.pointDown = new Array(this.topicList.length).fill(false);
this.firstTopic = response.data.data.topics[0].lessons[0].lessonId;
this.getFirstContent(this.firstTopic);
this.loadTopics = true;
});
},
Is there a possibility to make group item collapsible?
<FormulateInput type="group" name="employments" :repeatable="true" label="Employments"
add-label="+ Add Employment" #default="groupProps">
<!-- Clickable area -->
<div class="group text-sm font-semibold py-2 cursor-pointer relative" #click="groupProps.showForm">
....
</div>
<!-- Nested form: must be collapsible accordion -->
<div class="nested-form" v-show="groupProps.showForm">
....
</div>
</FormulateInput>
I thought to add showForm property to the group context.
For this I need to do Custom input types or is there some other way?
If anyone has any other ideas?
Thanks
I figured it out with the gist of #jpschroeder.
CollapsableGroupItem.vue:
<template>
<div class="group-item" :data-is-open="itemId === showIndex">
<div class="group group-item-title text-sm font-semibold py-2 cursor-pointer relative hover:text-blue-400" #click="toggleBody">
<slot name="title" v-bind="groupItem">#{{ context.index }}</slot>
</div>
<div class="group-item-body" v-show="itemId === showIndex">
<slot name="body">
<FormulateInput type="pelleditor" name="description" label="Description"/>
</slot>
</div>
</div>
</template>
<script>
export default {
name: "CollapsableGroupItem",
props: {
context: {
type: Object,
required: true,
},
showIndex: {
type: [Number, String],
required: true,
},
groupItem: {
type: Object,
required: true,
},
},
data () {
return {
itemId: this.context.name + this.context.index
}
},
created: function () {
// show current item
this.$emit("open", this.itemId);
},
methods: {
toggleBody() {
if (this.itemId === this.showIndex) {
// dont show anything
this.$emit("open", -1);
} else {
// show this one
this.$emit("open", this.itemId);
}
},
}
};
FormTemplate.vue:
<CollapsableGroupItem
:context="context"
:show-index="showIndex"
:group-item="educations[context.index]"
#open="showIndex = $event"
>
<template v-slot:title="education">
<span v-if="education.institution || education.degree"
>
{{ education.institution }}
<span v-if="education.institution && education.degree">at</span>
{{ education.degree }}
</span>
...
</template>
<template v-slot:body>
...
</template>
</CollapsableGroupItem>
Maybe it will help someone else or will be useful 😀
I have an input-component which has a form which collects start and finish times, job number and a select option.
This is attached to a data property with v-model.
This is then emitted with Event.$emit('addedData', this.hours)
In the display-component the Event.$on takes this data and checks an attribute and based on the check adds it to another data property (array) with this.todays_hours.push().
The template then displays this reactively using v-for in the template.
To this point all works fine. However when I then attempt to add another line of hours the hours already displayed change reactively with the input.
As my input-component also posts to a database with axios if I reload the page all is displayed correctly.
input-component
<template>
<div>
<div class="row">
<div class="col-2">
<input hidden="" v-model="hours.day">
</div>
<div class="col-2" >
<input type="time" v-model="hours.start">
</div>
<div class="col-2" >
<input type="time" v-model="hours.finish">
</div>
<div class="col-2" >
<input type="number" v-model="hours.job_number">
</div>
<div class="col-2" >
<select v-model="hours.climbing">
<option selected="selected" value="0">No</option>
<option value="1">Yes</option>
</select>
</div>
<div class="col-2" >
<button #click="onSave" class="btn-success btn-sm">Save</button>
</div>
</div>
<hr>
</div>
</template>
<script>
export default {
name: 'InputHoursComponent',
props: ['employeeId', 'dayCheck', 'weekEnding'],
data() {
return {
hours: {
start: "",
finish: "",
job_number: "",
climbing: 0,
day: this.dayCheck
},
climbing_select: ['No', 'Yes'],
}
},
methods: {
onSave()
{
axios.post('/payroll', {
employee_id: this.employeeId,
week_ending: this.weekEnding,
start: this.hours.start,
finish: this.hours.finish,
job_number: this.hours.job_number,
climbing: this.hours.climbing,
day: this.dayCheck
})
.then(response => {})
.catch(e => {this.errors.push(e)});
let data = this.normalizeProp(this.hours, s, true)
Event.$emit('onAddedEntry', data);
console.log("passed data:", this.hours);
}
}
}
</script>
display-component
<template>
<div>
<div v-for="item in todays_hours">
<div class="row">
<div class="col-2">
<div hidden="" ></div>
</div>
<div class="col-2" >
<div v-text="item.start"></div>
</div>
<div class="col-2" >
<div v-text="item.finish"></div>
</div>
<div class="col-2" >
<div v-text="item.job_number"></div>
</div>
<div class="col-2" >
<div v-text="(item.climbing)?'Yes':'No'"></div>
</div>
<div class="col-2" >
<button #click="onEdit" class="btn-warning btn-sm mb-1">Edit</button>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'DisplayHoursComponent',
props: ['dayCheck', 'hoursWorked'],
data() {
return {
hours_list: this.hoursWorked,
todays_hours: []
}
},
mounted() {
for (var i = 0; i < this.hours_list.length; i++) {
if (this.hours_list[i].day === this.dayCheck) {
this.todays_hours.push(this.hours_list[i])
}
}
Event.$on('onAddedEntry', (check) => {
if(check.day === this.dayCheck){
this.todays_hours.push(check);
}
})
},
methods: {
onEdit()
{
}
}
}
</script>
Can someone please help me?
Try pushing a copy of check instead of check itself.
Event.$on('onAddedEntry', (check) => {
if(check.day === this.dayCheck){
this.todays_hours.push({...check});
}
})
You could also make the copy when you emit the event instead.
Hello I have here one code with two "todo list" implementations in Vuejs but I have a problem.
1 Using a vue component i am getting a waring about how to use the parent variable.
2 Doing it on the main function I cannot keep the old value for the discard implementation.
please find the working code
Running! todo list in codepen
Vue.component('ntodo-item', {
template: '\
<transition name="fade">\
<div id="if" class="row" v-if="edit">\
<div class="col-md-7">\
<input class="form-control" v-model="title">\
</div>\
<div id="sssss" class="col-md-5">\
<button class="btn btn-danger roundButton" v-on:click="$emit(\'edit\')">Discard</button>\
<button class="btn btn-success roundButton" v-on:click="updateValue">Save</i></button>\
</div>\
</div>\
<div id="else" class="row" v-else>\
<div class="col-md-7">\
{{ title }}\
</div>\
<div id="ssaaas" class="col-md-5">\
<button class="btn btn-danger roundButton" v-on:click="$emit(\'remove\')">Remove</button>\
<button id="aaa" class="btn btn-default roundButton" v-on:click="$emit(\'edit\')">Edit</button>\
</div>\
</div>\
</transition>\
',
props: [
'title' ,
'edit'
],
methods: {
updateValue: function () {
this.$emit('input', this.title);
}
}
})
var app14 = new Vue({
el: '#app-14',
data: {
newTodoText: '',
newTodoText2: '',
todos: [
{
id: 1,
title: 'Do the dishes',
edit:0
},
{
id: 2,
title: 'Take out the trash',
edit:0
},
{
id: 3,
title: 'Mow the lawn',
edit:0
}
],
todos2: [
{
id: 1,
title: 'Do the dishes',
edit:0
},
{
id: 2,
title: 'Take out the trash',
edit:0
},
{
id: 3,
title: 'Mow the lawn',
edit:0
}
],
nextTodoId: 4,
nextTodoId2: 4
},
methods: {
addNewTodo: function () {
this.todos.push({
id: this.nextTodoId++,
title: this.newTodoText,
edit:0
})
this.newTodoText = ''
this.todos = _.orderBy(this.todos, 'id', 'desc');
},
editTodo: function (item){
// console.log(item.title)
item.edit^= 1
},
updateValue: function (item, newValue){
item.title=newValue
item.edit^= 1
},
addNewTodo2: function () {
this.todos2.push({
id: this.nextTodoId2++,
title: this.newTodoText2,
edit:0
})
this.newTodoText2 = ''
this.todos2 = _.orderBy(this.todos2, 'id', 'desc');
},
editTodo2: function (item){
console.log(item.title)
item.edit^= 1
},
deleteTodo2: function (item){
this.todos2.splice(item.id, 1);
},
updateValue2: function(text){
console.log(text);
}
}
})
.fade-enter-active, .fade-leave-active {
transition: opacity 0.3s, transform 0.3s;
transform-origin: left center;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
opacity: 0;
transform: scale(0.5);
}
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.13/dist/vue.js"></script>
<div class="col-md-12">
<div class="graybox">
<h5>app14</h5>
<div id="app-14">
`enter code here`<div class="row">
<div class="col-md-6">
<h5> todo list using "ntodo-item" component</h5>
<p>This one show me a warning because the child cannot edit the va passed by the parent but it is working and spected</p>
<input class="form-control"
v-model="newTodoText"
v-on:keyup.enter="addNewTodo"
placeholder="Add a todo"
>
<hr>
<ul>
<li
is="ntodo-item"
v-for="(todo, index) in todos"
v-bind:key="todo.id"
v-bind:title="todo.title"
v-bind:edit="todo.edit"
v-on:input="updateValue(todo, $event)"
v-on:remove="todos.splice(index, 1)"
v-on:edit="editTodo(todo)"
></li>
</ul>
</div>
<div class="col-md-6">
<h5> todo list update</h5>
<p> This one is working without any warn but I dont know how to discard changes. I dont want to create a temp var because I want to be able to edit all of them at the same time. </p>
<input v-model="newTodoText2"
v-on:keyup.enter="addNewTodo2"
placeholder="Add a todo"
class="form-control"
>
<hr>
<ul>
<transition-group name="fade" >
<li v-for="(todo2, index) in todos2":key="todo2.id">
<div id="if" class="row" v-if="todo2.edit">
<div class="col-md-7">
<input class="form-control" ref="todo2" v-model="todo2.title">
</div>
<div id="sssss" class="col-md-5">
<button class="btn btn-success roundButton" v-on:click="editTodo2(todo2)">ok</button>
</div>
</div>
<div id="else" class="row" v-else>
<div class="col-md-7">
{{todo2.title}}
</div>
<div id="ssaaas" class="col-md-5">
<button class="btn btn-danger roundButton" v-on:click="todos2.splice(index, 1)">Remove</button>
<button id="aaa" class="btn btn-default roundButton" v-on:click="editTodo2(todo2)">Edit</button>
</div>
</div>
</li>
</transition>
</ul>
</div>
</div>
</div>
</div>
</div>
.
Echoing my comment:
Create a local variable copy of your title prop and emit that variable's changes on edit. If they discard the edit just reset the local variable to the value of the title prop. Working example on CodeSandbox here.
Todo Item Component
<button class="btn btn-danger roundButton" #click="discardEdit">Discard</button>
...
data() {
return {
// our local copy
localTitle: null,
};
},
mounted() {
this.localTitle = this.title;
},
methods: {
updateValue: function() {
this.$emit("input", this.localTitle);
},
discardEdit: function() {
// just set local back to title prop value
this.localTitle = this.title;
this.$emit('edit');
},
}
I have a vue component (card-motor) with a prop named motor:
<div v-for="chunk in chunkDataMotores" class="row">
<div v-for="motor in chunk" class="col-md-6">
<card-motor :motor="motor"></card-motor>
</div>
</div>
Whenever data (motor) changes on the parent, the changes on the data property (id_color, id_motor, nombre _motor, etc...) of the component does not get updated. Here the card-motor component:
<template>
<div class="card" :data-motor-id="id_motor">
<div class="card-header" :style="backgroundColor">
<h4 class="text-center">{{nombre_motor}}<button class="btn btn-dark btn-sm pull-right" :data-motor-id="id_motor" #click="show_modal_colores(id_motor)">Color motor</button></h4>
</div>
<div class="card-body">
<div class="card">
<div class="card-header" role="tab" id="headingOne">
<div class="mb-0">
<a data-toggle="collapse" :href="computedId">
Piezas asociadas {{nombre_motor}} <i class="fa fa-caret-down" aria-hidden="true"></i>
</a>
<button #click="addPieza(id_motor)" class="btn pull-right" title="Añadir pieza nueva al motor"><i class="fa fa-plus text-info" aria-hidden="true"></i></button>
</div>
</div>
<div :id="id_motor" class="collapse" role="tabpanel" aria-labelledby="headingOne" data-parent="#accordion">
<div class="card-body">
<ul class="list-group">
<li class="list-group-item" v-for="pieza in piezas_motor">
<span class="badge badge-secondary">{{nombre_motor}}</span> {{pieza.pieza}}
<button class="btn btn-sm btn-danger pull-right"><i class="fa fa-trash" aria-hidden="true"></i></button>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['motor'],
data: function () {
return {
nombre_motor: this.motor.motor,
id_motor: this.motor.id,
id_color: this.motor.color.id,
piezas_motor: this.motor.piezas,
}
},
methods: {
show_modal_colores: function(id){
let $engine = $('#engine-colors');
$engine.data('motor-id', id);
$engine.find('div.color').removeClass('active');
$engine.find('div[data-id="'+this.activeColor+'"]').addClass('active');
$engine.modal('show');
},
addPieza(id) {
let $form = $('#form-pieza');
$form.data('motor-id', id);
$form.modal('show');
}
},
computed: {
computedId: function () {
return '#'+ this.id_motor;
},
backgroundColor: function () {
return 'background-color: '+ this.motor.color.codigo;
},
activeColor: function () {
return this.motor.color.id;
}
},
}
And here the parent code (root component):
Vue.component('card-motor', require('./components/CardMotor.vue'));
var app = new Vue ({
el: '#app',
data: {
dataMotores: [],
dataPuestos: [],
background_style: {
'background-color': ''
}
},
methods: {
makeActiveColor: function(e) {
$(e.currentTarget).closest('.modal-body').find('div.color').removeClass('active');
$(e.currentTarget).closest('div.color').addClass('active');
},
changeColor: function(e) {
let vm = this;
let id=$(e.currentTarget).closest('div.modal-content').find('.active').data('id');
let motor_id = $(e.currentTarget).closest('#engine-colors').data('motor-id');
axios.post('/admin/motores/change-color', {idmotor:motor_id, idcolor: id})
.then(response=>{
this.getData();
$('#engine-colors').modal('hide');
});
},
getData: function(){
axios.get('/admin/motores/api/data')
.then(response => {
this.dataMotores = response.data.motores;
this.dataPuestos = response.data.puestos;
})
.catch();
}
},
computed: {
chunkDataMotores() {
return _.chunk(this.dataMotores, 2);
}
},
created: function() {
this.getData();
}
});
Data returned from the axios call to the server are arrays of objects (getData method). Computed properties updates properly on the component, but not the data property.
You are making copies of your props, so the component renders, make your copies inside data(), but data() is called once, so when the parent component updates the child does not update.
data: function () {
return {
nombre_motor: this.motor.motor,
id_motor: this.motor.id,
id_color: this.motor.color.id,
piezas_motor: this.motor.piezas,
}
},
You can use motors prop directly, like:
<div class="card-header" :style="backgroundColor">
<h4 class="text-center">
{{ motor.motor }}
<button class="btn btn-dark btn-sm pull-right"
:data-motor-id="motor.id"
#click="show_modal_colores(motor.id)">
Color motor
</button>
</h4>
</div>
You need to pass value of dataMotores in components
<card-motor :motor="dataMotores"></card-motor>