Vue - как связать свойства документа / окна с вычисляемым свойством?

Я хотел бы прослушивать все события фокуса на входах в моем приложении Vue. Чтобы получить текущий фокус ввода, я подумал о привязке свойства document.activeElement к вычисляемому свойству в моем компоненте приложения, но это не является реактивным, почему?

Объявление activeElement в данных также не является реактивным.

То же самое и для наблюдателей!

Единственный способ заставить его работать - просто вернуть значение после события focus / blur на самом входе, но это не соответствует моим потребностям.

new Vue({
  el: "#app",
  data: {
    activeElem: document.activeElement.tagName,
    realActiveElem: document.activeElement.tagName,
  },
  methods: {
    getActiveElem() {
      this.realActiveElem = document.activeElement.tagName;
    }
  },
  computed: {
    focused() {
      return document.activeElement.tagName;
    }
  },
  watch: {
    activeElem(val, oldVal) {
      console.log(val !== oldVal);
    },
    focused(val, oldVal) {
      console.log(val !== oldVal);
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <h2 @focus="getActiveElem()">
    Data: {{activeElem}}
  </h2>
  <h2>
    Computed: {{focused}}
  </h2>
  <h2>
    From function to data: {{realActiveElem}}
  </h2>
  <input placeholder="Focus/Blur me" id="test" @focus="getActiveElem()" @blur="getActiveElem()" />
</div>

Есть ли способ привязать свойства документа или окна как реактивные?


person Pierre Burton    schedule 02.08.2019    source источник


Ответы (1)


Vue может реагировать только на изменения, внесенные в данные, но не на DOM. Изменение в document.activeElement - это изменение DOM.

Вы можете использовать событие для запуска метода обновления данных. Например:

new Vue({
  el: "#app",
  data: {
    element: ""
  },
  created() {
    document.addEventListener("focusin", this.focusChanged);
  },
  beforeDestroy() {
    document.removeEventListener("focusin", this.focusChanged);
  },
  methods: {
    focusChanged(event) {
      this.element = event.target.tagName;
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <input id="mine">
  <p>{{ element }}</p>
</div>

person Scribblemacher    schedule 02.08.2019
comment
Достаточно чисто для меня! Спасибо ! - person Pierre Burton; 02.08.2019