Элемент vue.js, выбранный фокусом, не является реактивным

У меня есть слушатель, чтобы проверить, какой ввод был выбран наконец, чтобы добавить в него какую-то строку / переменную.

created: function () {
    document.addEventListener('focusin', this.focusChanged);
}

focusChanged(event) {
    if (event.target.id !== 'variable-search') {
        this.lastElement = event.target;
    }
}

Кажется, это работает нормально, и когда я нажимаю на поле ввода, this.lastElement обновляется с выбранным элементом. Все эти входы имеют v-model, который может быть строкой в ​​объекте или просто строкой.

Теперь дело в том, что я пытаюсь обновить значение с помощью:

this.lastElement.value += variable;

Vue не обнаруживает своих изменений, также в инструментах Vue Developer строка не обновляется. Но в поле ввода он обновляется. Так что это должно быть связано с реактивностью.

Когда я добавляю новый символ в поле ввода (v-модель), он снова обновляется. Так что просто когда я обновляю строку на this.lastElement, она не регистрирует свои изменения.

Дело в том, что поля ввода являются динамическими, поэтому я не знаю, сколько здесь полей ввода и сколько списков и т. Д. Поэтому мне нужно, чтобы Vue повторно визуализировал переменную после обновления значения lastElement.

Изменить

Я просто попробовал это с @focus вот пример

<input v-model="testVar" @focus="lastElement = testVar">

Если я обновлю lastElement позже, он обновит его не для testVar, а только для lastElement.


person Jelmer de Vries    schedule 01.02.2019    source источник
comment
Вам необходимо обновить значение lastElement через привязку с v-моделью, потому что this.lastElement хранит ссылку на элемент dom, но его значение контролируется моделью vue.   -  person thefallen    schedule 01.02.2019
comment
@thefallen в данном случае это просто невозможно, потому что я не могу напрямую получить доступ к v-модели.   -  person Jelmer de Vries    schedule 01.02.2019
comment
@JelmerdeVries Почему вы не можете использовать вместо этого v-on:focus?   -  person Yom T.    schedule 01.02.2019
comment
Я тоже пробовал это. Он просто не регистрирует изменения, потому что значение элемента изменяется с помощью javascript. Сейчас я пробую другой подход. Я буду держать вас в курсе, ребята, никогда не было такой проблемы с Vue, ха-ха.   -  person Jelmer de Vries    schedule 01.02.2019
comment
Я просто снова попробовал @focus и установил lastElement на текущий элемент v-модели. Допустим, у меня есть ввод: '‹input v-model = test @ focus = lastElement = test›, если я обновляю значение lastElement после этого, он не обновляет тест ..   -  person Jelmer de Vries    schedule 01.02.2019
comment
Не могли бы вы показать нам код, который вы использовали, когда пробовали @focus?   -  person D Malan    schedule 01.02.2019
comment
@DelenaMalan обновил его!   -  person Jelmer de Vries    schedule 01.02.2019
comment
Возможно, будет лучше, если вы объясните, чего хотите достичь. Вы генерируете некоторые поля ввода динамически, а затем что должно произойти?   -  person mbuechmann    schedule 01.02.2019
comment
Это динамическая почтовая система, в которой вы можете редактировать письма. В этих письмах вы можете использовать какие-то переменные, например адрес. Эти переменные можно ввести прямо в поля ввода или нажать кнопку, например, содержащую адрес. Если вы нажмете на эту кнопку, к значению добавится только адрес. Если вы нажмете эту кнопку прямо сейчас в первой версии, он обновит вводимый текст, но не будет зарегистрирован во Vue. Таким образом, они видят тестовую строку address, в то время как vue регистрирует только тестовую строку, если они напечатают что-нибудь после address, она снова обновится. Тай за помощь кстати   -  person Jelmer de Vries    schedule 01.02.2019
comment
Вы управляете элементами dom с помощью функций dom. По этой причине эти элементы не регистрируются в vue. У вас должна быть некоторая структура данных в вашем компоненте, которая отображается в шаблоне. Когда вы нажимаете кнопку, вы должны добавлять данные во внутреннюю структуру данных. Если вы это сделаете, он будет отрисован автоматически.   -  person mbuechmann    schedule 01.02.2019
comment
Просто для пояснения: вы хотите динамически добавлять значения для определенных ключей в произвольную структуру данных (в данном случае по электронной почте). Это можно сделать через поле ввода (где вы отображаете поле ввода для каждой возможной клавиши) или через кнопку, которая добавит предопределенное значение для определенного ключа. Это верно?   -  person mbuechmann    schedule 01.02.2019
comment
После изменения значения в lastElement вам необходимо lastElement отправить событие input или change, чтобы Vue распознал, что что-то произошло.   -  person Roy J    schedule 01.02.2019


Ответы (2)


Программное изменение значений в элементах DOM не вызывает срабатывания событий DOM. v-model полагается на события input (или change при использовании .lazy) для обновления своей связанной переменной. Если вы отправляете эти события при обновлении значения во входных данных, переменная отреагирует.

new Vue({
  el: '#app',
  data: {
    items: ['one','two','three']
  },
  methods: {
    addAddress() {
      this.lastElement.value += 'address';
      this.lastElement.dispatchEvent(new Event('input'));
      this.lastElement.dispatchEvent(new Event('change'));
    },
    focusChanged(event) {
      this.lastElement = event.target;
    }
  }
})
<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<div id="app">
  <div v-for="item, index in items">
    <input v-model="items[index]" @focus="focusChanged">
    {{item}}
  </div>
  <button type="button" @click="addAddress">+address</button>
</div>

person Roy J    schedule 01.02.2019
comment
Ты герой! Спасибо за помощь. - person Jelmer de Vries; 01.02.2019

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

<input v-model="testVar" ref="input1" id="input1" @focus="focusChanged">

В ваших методах:

 methods: {
      focusChanged(event) {
            if (event.target.id !== 'variable-search') {
                this.lastElement = event.target.id;
            }
        },
 }

И где вы хотите обновить значение: this.$refs[this.lastElement].value += variable;

person D Malan    schedule 01.02.2019
comment
Спасибо за ответ, попробую! - person Jelmer de Vries; 01.02.2019
comment
Я думаю, что это не оптимальное решение, поскольку документы vuejs советуют использовать ref только в крайних случаях. - person mbuechmann; 01.02.2019
comment
Хорошо, это делает то же самое, он снова обновляет текст, но vue не регистрирует его. Таким образом, переменная добавляется к значению ввода на экране, но vue по-прежнему имеет старую строку. Если вы обновите строку до 1 символа, она обновится правильно (но это то же самое, что и в моих версиях). - person Jelmer de Vries; 01.02.2019