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

#vue.js

#vue.js

Вопрос:

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

Я уже пытался http://www.jacklmoore.com/autosize /, но у него та же проблема.

Я создал изолированную среду, которая показывает проблему при вводе поля, которое обновляется, но не при динамическом изменении значения

Живой пример: https://codesandbox.io/s/53nmll917l

проблема в действии

Комментарии:

1. Вам нужно использовать слот для текстовой области? Кажется, довольно легко решить проблему, если вы могли бы включить текстовую область в шаблон компонента.

2. Не обязательно, текстовая область также может быть включена в шаблон. Я попробовал, но безуспешно. Проблема в том, что я не знаю, как перехватить событие при изменении данных.

Ответ №1:

Вам нужен triggerInput() метод:

 triggerInput() {
  this.$nextTick(() => {
    this.$refs.resize.$el.dispatchEvent(new Event("input"));
  });
}
  

использовать всякий раз, когда вы программно изменяете значение, запуская логику изменения размера, используемую <textarea> в «реальных» input событиях.

Обновленный codesandbox.

Примечание: без $nextTick() оболочки недавно измененное значение еще не будет применено, и, несмотря на input срабатывание, элемент еще не был обновлен, и изменение размера происходит до value того, как изменилось, в результате чего старое height выглядит так, как будто этого не произошло.

Ответ №2:

Не совсем понимаю ответы, опубликованные здесь. Вот мое простое решение:

 <textarea
   rows="1"
   ref="messageInput"
   v-model="message"
/>
  
 watch: {
    message: function(newItem, oldItem) {
      let { messageInput } = this.$refs;
      const lineHeightInPixels = 16;
      
      // Reset messageInput Height
      messageInput.setAttribute(
          `style`,
          `height:${lineHeightInPixels}px;overflow-y:hidden;`
      );

      // Calculate number of lines (soft and hard)
      const height = messageInput.style.height;
      const scrollHeight = messageInput.scrollHeight;
      messageInput.style.height = height;
      const count = Math.floor(scrollHeight / lineHeightInPixels);

      this.$nextTick(() => {
        messageInput.setAttribute(
            `style`,
            `height:${count*lineHeightInPixels}px;overflow-y:hidden;`
        );
      });
    },
}
  
 <style scoped>
textarea {
  height: auto;
  line-height: 16px;
}
</style>