i have a list of tasks (each task is inside a div), and i want to create a function so that if a task was clicked its border becomes red and if a different task was clicked the border of the previous one should turn normal and the new one's border should become red, there is a file called task for one task and tasks which implements task and shows all tasks, i've tried different ways and searched about the subject, but it's too difficult to seearch about this exact problem, i always get irrelevant results, if u guys know a source or a better way to get information then it's sufficient, if there's no other way here's the code in my files, thank u all so much (i've deleted styling and comments to make code shorter and easier to read, hope it won't cause issue)
code in task file
<template>
<div @dblclick="$emit('togglereminder', task.id)" :>
<h3>{{ task.text }}</h3>
<p>{{ task.id }}</p>
</div>
</template>
<script>
export default {
name: "Task",
props: {
task: Object,
},
};
</script>
code in tasks file:
<template>
<div :key="task.id" v-for="task in tasks">
<Task :task="task" @togglereminder="$emit('togglereminder', task.id)" />
</div>
</template>
<script>
import Task from "./task.vue";
export default {
name: "Tasks",
props: {
tasks: Array,
},
components: {
Task,
},
emits: ["togglereminder"],
};
</script>
CodePudding user response:
You can toggle class with prop and method
Vue.component('Task', {
template: `
<div @click="$emit('togglereminder', task.id)" :>
<h3>{{ task.text }}</h3>
<p>{{ task.id }}</p>
</div>
`,
props: {
task: Object,
cls: Number
}
})
new Vue({
el: "#demo",
data() {
return {
tasks: [{id: 1, text: 'aaa'}, {id: 2, text: 'bbb'}],
sel: null
}
},
methods: {
selected(e) {
this.sel = e
}
}
/*props: {
tasks: Array,
},
emits: ["togglereminder"],*/
})
.task {
border: 2px solid red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
<div :key="task.id" v-for="task in tasks">
<task :task="task" :cls="sel" @togglereminder="selected" />
</div>
</div>
CodePudding user response:
This is basic state management: have a parent component that is aware of the task list and the currently active task, and a task component that is only aware of whether or not is active. You don't need any fancy event handling, you're just passing data via props!
Vue.config.productionTip = false;
const Task = {
name: 'Task',
props: ['onClick', 'isActive'],
template: `<div : v-on:click="onClick"></div>`,
}
const App = new Vue({
el: '#root',
components: { Task },
data: {
activeTaskId: null,
},
methods: {
handleClick(taskId) {
this.activeTaskId = taskId;
},
},
template: `<div><Task :onClick="() => handleClick(0)" :isActive="activeTaskId === 0" /><Task :onClick="() => handleClick(1)" :isActive="activeTaskId === 1" /><Task :onClick="() => handleClick(2)" :isActive="activeTaskId === 2" /></div>`,
});
.task {
width: 200px;
height: 15px;
border: 1px solid black;
margin: 10px;
}
.active {
border: 1px solid red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="root"></div>
