I have a modal window component that opens when task is clicked
<template lang="pug">
.modal-task(:style="{display: showDetailsModal}")
.modal-task-details
.task
| {{task.id}}
.name(v-show="show")
|Name: {{task.name}}
.text(v-show="!show")
textarea(v-model='task.name')
.status
|Status: {{task.status}}
.text(v-show="!show")
textarea(v-model='task.status')
.deadline
|Deadline: {{task.time}}
.description(v-show="show")
|description: {{task.description1}}
.text(v-show="!show" @change="handleChange")
textarea(v-model='task.description1')
button(class='add-task' v-on:click="show=!show" v-show="show") Edit
button(class='add-task' v-on:click="show=!show" v-show="!show" @click="closeForm()") Close
button(class='add-task' v-show="showSaveButton" @click="saveTask(task)") Save
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import { emitter } from '../main'
export default defineComponent({
name: 'task-details-modal',
props: ['showDetailsModal', 'task'],
data () {
return {
show: true,
showSaveButton: true,
updatedTask: {
name: '',
description1: '',
time: '',
status: ''
}
}
},
methods: {
closeForm () {
emitter.emit('close', this.updatedTask)
},
saveTask () {
emitter.emit('save', this.task)
},
handleChange () {
this.showSaveButton = true
}
},
created () {
this.updatedTask = JSON.parse(JSON.stringify(this.task))
console.log(this.updatedTask)
}
})
</script>
And I can open it from this component (when I click on the task in this component, then created from the modalk is triggered)
<template lang="pug">
.asd(v-if="Object.keys(this.task).length !== 0" :v-if="showDetailsModal === 'block'")
task-details-modal(:showDetailsModal = 'showDetailsModal' :task = 'task')
.task(v-for='(task, index) in tasks' :key='task.index' draggable="true" @dragstart="startDrag($event, task)" @click="openModal(index)")
.card()
.name()
| {{task.name}}
.deadline
| {{task.time}}
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import { TaskStatusEnum } from './../enums/TaskStatusEnum'
import TaskDetailsModal from '@/components/TaskDetailsModal.vue'
import { emitter } from '../main'
export default defineComponent({
name: 'tasks-order-by-status',
props: ['tasks'],
components: {
TaskDetailsModal
},
data () {
return {
TaskStatusEnum,
showDetailsModal: 'none',
task: {}
}
},
methods: {
openModal (index) {
this.showDetailsModal = 'block'
this.task = this.tasks[index]
},
startDrag (event, item) {
event.dataTransfer.dropEffect = 'move'
event.dataTransfer.effectAllowed = 'move'
event.dataTransfer.setData('itemName', item.name)
event.dataTransfer.setData('itemStatus', item.status)
}
},
mounted () {
emitter.on('close', () => {
this.showDetailsModal = 'none'
})
emitter.on('save', () => {
this.showDetailsModal = 'none'
})
}
})
</script>
and from this (and when I click on the task in this component, then created from the modalk works only once, when I click on any task, then created does not work)
<template lang="pug">
.tasks
.asd(v-if="Object.keys(this.task).length !== 0" :v-if="showDetailsModal === 'block'")
task-details-modal(:showDetailsModal = 'showDetailsModal' :task = 'task')
task-modal(:showModal = 'showModal' :tasks = 'tasks'
@close-modal="showModal = $event")
h2
span Tasks
button(class='add-task' @click="openModal()")
.nadesti
.nades
span Name
span Description
span Deadline
.task(v-for='(task, index) in tasks' :key='task.index' :ref="`task${index}`" @click="taskModal(index)")
.name
| {{task.name}}
.description
| {{task.description1}}
.time
| {{task.time}}
button(class='delete-task' @click="deleteCart(index)") -
</template>
<script lang="ts">
import { computed, defineComponent } from 'vue'
import { TaskInterface } from '@/types/task.interface'
import useValidate from '@vuelidate/core'
import { required } from '@vuelidate/validators'
import { emitter } from '../main'
import { TaskStatusEnum } from './../enums/TaskStatusEnum'
import TaskModal from '@/components/TaskModal.vue'
import TaskDetailsModal from '@/components/TaskDetailsModal.vue'
import { useStore } from 'vuex'
export default defineComponent({
setup () {
const store = useStore()
const tasks = computed(() => store.state.tasks)
return {
tasks
}
},
components: {
TaskModal,
TaskDetailsModal
},
data () {
return {
v$: useValidate(),
task_name: '',
task_deadline: '',
task_description: '',
task_status: '',
TaskStatusEnum,
showModal: 'none',
showDetailsModal: 'none',
task: ''
}
},
methods: {
taskModal (index) {
this.task = this.tasks[index]
this.showDetailsModal = 'block'
}
},
mounted () {
emitter.on('save', task => {
const index = task as TaskInterface
this.tasks[index.id] = task
this.showDetailsModal = 'none'
})
emitter.on('close', task => {
const index = task as TaskInterface
this.tasks[index.id].name = index.name
this.showDetailsModal = 'none'
})
}
})
</script>
How can I make created work every time I click on a task?
CodePudding user response:
The reason is runs once is because the instance of the component remains after the v-model
is triggered off.
For example, let's say I have these components:
<MainView>
<ListComponent />
</MainView>
And when I click something, a new modal component pops up. Now it looks like this.
<MainView>
<ListComponent />
<ModalComponent />
</MainView>
So now that the component exists, the created
method will run. Now I hide the modal by triggering its v-model
to false. The component disappears from the display, but the component is still loaded. It will still look like this:
<MainView>
<ListComponent />
<ModalComponent />
</MainView>
Because the component still exists and is only hidden because of the v-model
, showing it again will not run created
again. You will need to ensure that the instance is fully removed from the DOM, which you can do through a v-if
at the component import:
<ModalComponent v-if="myCondition" />
I recommend using VueTools to see this process in detail.