Компонент используется в нескольких местах, все обновляются одновременно - PullRequest
0 голосов
/ 20 апреля 2020

Я еще новичок в Vue У меня есть компонент, который используется для приема и отображения файлов, когда они перетаскиваются на компонент. Согласно документации, если у меня есть свои атрибуты в функции данных, я могу использовать этот компонент в нескольких местах и ​​обновлять их независимо от другого компонента.

Это не тот случай, когда я тестирую компонент на экране добавления, компонент на экране просмотра все еще обновляется с теми же данными. Я не могу понять, почему это происходит, поэтому мне было интересно, смогу ли я получить несколько свободных глаз, чтобы взглянуть или указать мне правильное направление, как я могу решить эту проблему.

это мой ImageViewer код

<template>
  <div id="image-panel"
       @dragenter="allowDrag"
       @mouseenter="toggleSingleViewActionbar('show')"
       @mouseleave="toggleSingleViewActionbar('hide')">
    <div id="dragDropOverlay" class="drop display-inline align-center"
         :class="[isOverlay ? 'overlay' : '']"
         @dragleave="retainOverlay"
         @dragover.prevent
         @drop="onDrop">
      <div class="overlay-text">Drag files here</div>
    </div>
      <single-view v-if="display === 'single'"
                   :file-list-length="this.fileList.length === 0 ? 0 : this.fileList.length - 1"
                   :current-position="currentPosition"
                   :display-type="displayType"
                   v-on:addToFileList="updateFileList"/>
      <grid-view v-else
                 :file-list-length="this.fileList.length === 0 ? 0 : this.fileList.length - 1"
                 :current-position="currentPosition"/>
      <app-image-section-single-view
        v-if="display === 'single'"
        :fileList="fileList"
        :currentPosition="currentPosition"
        :is-overlay="isOverlay"
        />
      <app-image-section-grid-view v-else :file-list="fileList"/>
    <snack-bar v-if="deleteConfirmation" message="Are you sure you want to delete this file?"></snack-bar>
  </div>
</template>

<script>
import ImageSectionSingleView from './ImageSectionSingleView'
import ImageSectionGridView from './ImageSectionGridView.vue'
import { eventBus } from '@/main'
import Singleview from '../Actionbar/Singleview'
import Gridview from '../Actionbar/Gridview'
import SnackBar from '../SnackBar/SnackBar'
import { states } from '../enums/enums'

export default {
  data () {
    return {
      fileList: [],
      currentPosition: 0,
      display: 'single',
      displayType: '',
      isOverlay: false,
      deleteConfirmation: false
    }
  },
  watch: {
    fileList () {
      eventBus.$emit('updateFileList', this.fileList)
    }
  },
  methods: {
    onDrop (e) {
      e.stopPropagation()
      e.preventDefault()
      if (!this.isOverlay) return
      this.updateFileList(e.dataTransfer.files)
      this.isOverlay = false
    },
    allowDrag () {
      this.isOverlay = this.$store.getters.appState !== states.view
    },
    retainOverlay (event) {
      if (!this.isOverlay) return
      this.isOverlay = !!event.relatedTarget.closest('#dragDropOverlay')
    },
    getFileList () {
      return this.$store.getters.getFileList
    },
    updateFileList (files) {
      this.fileList.push.apply(this.fileList, (
        [...files].map((f) => ({
          name: f.name,
          data: URL.createObjectURL(f),
          type: f.type
        }))))
      this.currentPosition = this.fileList.length - 1
    },
    getCurrentPosition () {
      return this.$store.getters.getCurrentPosition
    },
    // updateCurrentPosition (position) {
    //   this.$store.commit('updateCurrentPosition', position)
    // },
    toggleSingleViewActionbar (action = '') {
      this.displayType = action
    },
    deleteImage (index = -1) {
      if (index === -1) {
        index = this.currentPosition
      }
      this.fileList.splice(index, 1)
      if (index < this.fileList.length) return
      if (this.currentPosition > 0) {
        this.currentPosition--
      }
    },
    deleteSelected (indexes) {
      for (let i = 0; i < indexes.length; i++) {
        this.deleteImage(indexes[i])
      }
      this.fileList.map((file) => {
        file.isVisible = false
      })
    }
  },
  created () {
    this.fileList = this.getFileList()
    this.currentPosition = this.getCurrentPosition()
    eventBus.$on('deleteSelectedFiles', (indexes) => {
      this.deleteSelected(indexes.sort().reverse())
      if (this.fileList.length === 0) {
        this.currentPosition = 0
        this.display = 'single'
      }
    })
    eventBus.$on('setSelectedFiles', (state) => {
      this.fileList.map((file) => {
        file.isVisible = state
      })
    })
    eventBus.$on('moveToNextFile', (positionNext) => {
      this.currentPosition = positionNext++
    })
    eventBus.$on('moveToPreviousFile', (positionPrevious) => {
      this.currentPosition = positionPrevious--
    })
    eventBus.$on('confirmDelete', () => {
      eventBus.$emit('singleDeleteConfirmation', () => {
      })
    })
    eventBus.$on('confirmationYes', () => {
      this.deleteImage()
      eventBus.$emit('singleDeleteSnackbarClose')
    })
    eventBus.$on('confirmationNo', () => {
      eventBus.$emit('singleDeleteSnackbarClose')
    })
    eventBus.$on('switchView', (value) => {
      this.display = value
    })
    eventBus.$on('singleDeleteConfirmation', () => {
      this.deleteConfirmation = !this.deleteConfirmation
    })
    eventBus.$on('singleDeleteSnackbarClose', () => {
      this.deleteConfirmation = false
    })
  },
  components: {
    appImageSectionSingleView: ImageSectionSingleView,
    appImageSectionGridView: ImageSectionGridView,
    singleView: Singleview,
    gridView: Gridview,
    SnackBar: SnackBar
  }
}
</script>

и вот где отображается изображение / файл

<template>
  <div class="display-inline">
    <img @dragenter="isOverlay=true" v-if="fileList.length > 0" :src="fileList[currentPosition].data" class="img" />
    <img v-else src="../../../src/assets/logo.png" class="img" />
  </div>
</template>

<script>

export default {
  props: {
    fileList: Array,
    currentPosition: Number,
    fileListLength: Number,
    isOverlay: Boolean
  }
}
</script>

Как я могу получить его так, чтобы он отображался независимо в каждом из моих разделов, где вызывается компонент

1 Ответ

0 голосов
/ 20 апреля 2020

Изначально все свойства данных независимы, но затем вы присваиваете this.fileList = this.getFileList(), который получает массив из хранилища. Все компоненты будут использовать этот же массив в своем свойстве fileList. - Комментарий от skirtle

...