получение цели дочернего компонента vue события родительского компонента - PullRequest
0 голосов
/ 17 сентября 2018

Я экспериментирую с Vue.js, и у меня есть родительский компонент с некоторыми дочерними компонентами.То, что я хочу сделать, это отслеживать компоненты, которые «перетаскиваются».

Это пример, чтобы понять мою проблему.

Пока чтоя имею в виду, что пользователь инициирует событие mousedown в родительском компоненте, которое условно активирует прослушиватели mouseover в дочерних компонентах, где я отслеживаю, какие дочерние компоненты были перемещены.Когда пользователь отпускает кнопку мыши, mouseover прослушиватели удаляются.

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

Чтобы решить эту проблему, я получаю event.target.__vue__ события mousedown для доступадочерний компонент и явно вызвать метод отслеживания.(Строка 25 файла App.vue в примере)

Мой вопрос: есть ли более подходящий Vue.js способ запуска метода отслеживания дочернего компонента, который находится ниже начального значения mousedown, которое происходит народитель кроме использования event.target.__vue__?Или вообще есть лучший способ отследить, какие дочерние компоненты «перетаскиваются»?

1 Ответ

0 голосов
/ 18 сентября 2018

Если у вашего родительского компонента и дочернего компонента существует тесная связь (например, дочерний компонент должен быть размещен внутри родительского компонента), возможно, вы захотите попробовать Vue Обеспечить и ввести :

  1. родительский компонент предоставляет один метод, позволяющий дочерним элементам регистрировать свои дорожки, а затем использует provide для его передачи (ниже демонстрационной версии передайте экземпляр по ключевому слову this) дочерним элементам.

  2. каждому дочернему компоненту просто нужно вызвать этот метод для загрузки своих треков в родительский.

Но для обеспечения / ввода, обратите внимание на это:

Примечание: привязки подачи и впрыска НЕ ​​являются реактивными. Это намеренным. Однако, если вы передадите наблюдаемый объект, свойства на этом объекте остаются реактивными.

Ниже одно простое демо :

Vue.config.productionTip = false

Vue.component('so-parent', {
  provide() {
    return {
      _tracker: this
    }
  },
  template: `
    <div @mousedown="toggleTrack(true)" @mouseup="toggleTrack(false)"><h3>children count: {{children.length}} - tracking: {{trackState}}</h3><h3>{{tracks}}</h3><slot></slot></div>
  `,
  data() {
    return {
      children: [],
      tracks: [],
      trackState: false
    }
  },
  methods: {
    _registerChild(child) {
      this.children.push(child)
    },
    _registerTracks(track) {
      if (this.trackState) this.tracks.push(track)
    },
    toggleTrack: function(state) {
      this.trackState = state
      if(!this.trackState) {
        this.tracks = []
      }
    }
  }
})

Vue.component('so-child', {
  inject: {
    _tracker: {
      default () {
        console.error('so-child must be child of so-parent')
      }
    }
  },
  data() {
    return {
      childState: false,
      childSeq: 0
    }
  },
  props: ['cid'],
  render(h) {
    return h('div', {
      class: 'child',
      on: {
        mouseover: () => this._tracker._registerTracks(this.cid)
      }
    }, [this.childSeq + ' Child Component ' + this.cid, this.$slots.default])
  },
  mounted() {
    this.childSeq = this._tracker.children.length
    this._tracker._registerChild(this)
  }
})

new Vue({
  el: '#app'
})
div.child {
  border: 1px solid;
  display: inline-block;
  padding: .5em 1em;
  margin: 0 0.5em 1em;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  &:hover {
    background: #b2bde3;
    cursor: pointer;
    color: white;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>

<div id="app">
  <so-parent>
    <so-child cid="A"></so-child>
    <so-child cid="B"></so-child>
    <so-child cid="C"></so-child>
    <so-child cid="D"></so-child>
  </so-parent>
</div>
...