Home > Mobile >  Why does created () not work everywhere when opening modals from different components?
Why does created () not work everywhere when opening modals from different components?

Time:12-23

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.

  • Related