Input подлагивает когда использую emit во vue

от admin

Vue 3, $ emit никогда не срабатывает

Вы должны импортировать дочерний компонент в родительский компонент и использовать его вместо обычного тега div .

Я поделюсь с вами примерами для достижения эмиссии в Vue 3 с помощью <script setup> и Composition API. Я настоятельно рекомендую использовать <script setup , если вы собираетесь использовать Composition API в однофайловом компоненте. Однако выбор за вами.

Вы должны импортировать этот дочерний компонент в родительский. И не переименовывайте его в исходный тег html .vue3. Вам лучше использовать Composition API.

Slow inputs with Vue and Vue Material

I’m using VueJs 2.0 with Vue Material. I’m rendering a table with quite a few rows that contains multiple input fields and/or select fields (VueMaterial components).

When entering data into the inputs the components becomes quite slow. Here is a live demo on JSFiddle to better demonstrate the issue.

Try keeping a letter in when typing in the text input. With more rows even normal typing gets quite slow.

Any idea how to fix this?

3 Answers 3

It seems the problem is with Vue-Material. There is already a bug logged for this. https://github.com/marcosmoura/vue-material/issues/544

Seems like removing the second select box eases things up (see an updated demo).

Do you really need two identical select boxes?

a long time has passed but I think I have found a solution to make it a little better. First you need to fork the repo otherwise you will need to create pull requests to the official repo that is more or less abandoned. Once created the fork just open:

Go to line 41 and remove:

I don’t understand why this, I think they wanted to cache the list in some way but this just cause to cycle options twice making the component heavier. Especially with a lot of options.

I tested the component in several way and it seems to work fine now.

To be sincere I had to apply other fixes to make it work properly but not related to this topic.

Unfortunately the repo is abandoned, it is just code to fork to save some time but needs to be maintained and improved.

Input подлагивает когда использую emit во vue

I’m using VueJs 2.0 with Vue Material. I’m rendering a table with quite a few rows that contains multiple input fields and/or select fields (VueMaterial components).

When entering data into the inputs the components becomes quite slow. Here is a live demo on JSFiddle to better demonstrate the issue.

Try keeping a letter in when typing in the text input. With more rows even normal typing gets quite slow.

Any idea how to fix this?

3 Answers 3

Trending sort

Trending sort is based off of the default sorting method — by highest score — but it boosts votes that have happened recently, helping to surface more up-to-date answers.

It falls back to sorting by highest score if no posts are trending.

Switch to Trending sort

It seems the problem is with Vue-Material. There is already a bug logged for this. https://github.com/marcosmoura/vue-material/issues/544

Seems like removing the second select box eases things up (see an updated demo).

Do you really need two identical select boxes?

a long time has passed but I think I have found a solution to make it a little better. First you need to fork the repo otherwise you will need to create pull requests to the official repo that is more or less abandoned. Once created the fork just open:

Go to line 41 and remove:

I don’t understand why this, I think they wanted to cache the list in some way but this just cause to cycle options twice making the component heavier. Especially with a lot of options.

I tested the component in several way and it seems to work fine now.

To be sincere I had to apply other fixes to make it work properly but not related to this topic.

Unfortunately the repo is abandoned, it is just code to fork to save some time but needs to be maintained and improved.

Vue 3, $ emit никогда не срабатывает

Component Events #

This page assumes you’ve already read the Components Basics. Read that first if you are new to components.

Emitting and Listening to Events #

A component can emit custom events directly in template expressions (e.g. in a v-on handler) using the built-in $emit method:

The $emit() method is also available on the component instance as this.$emit() :

The parent can then listen to it using v-on :

The .once modifier is also supported on component event listeners:

Like components and props, event names provide an automatic case transformation. Notice we emitted a camelCase event, but can listen for it using a kebab-cased listener in the parent. As with props casing, we recommend using kebab-cased event listeners in templates.

Unlike native DOM events, component emitted events do not bubble. You can only listen to the events emitted by a direct child component. If there is a need to communicate between sibling or deeply nested components, use an external event bus or a global state management solution.

Event Arguments #

It’s sometimes useful to emit a specific value with an event. For example, we may want the <BlogPost> component to be in charge of how much to enlarge the text by. In those cases, we can pass extra arguments to $emit to provide this value:

Then, when we listen to the event in the parent, we can use an inline arrow function as the listener, which allows us to access the event argument:

Or, if the event handler is a method:

Then the value will be passed as the first parameter of that method:

All extra arguments passed to $emit() after the event name will be forwarded to the listener. For example, with $emit(‘foo’, 1, 2, 3) the listener function will receive three arguments.

Declaring Emitted Events #

Emitted events can be explicitly declared on the component via the defineEmits() macro emits option :

The $emit method that we used in the <template> isn’t accessible within the <script setup> section of a component, but defineEmits() returns an equivalent function that we can use instead:

The defineEmits() macro cannot be used inside a function, it must be placed directly within <script setup> , as in the example above.

If you’re using an explicit setup function instead of <script setup> , events should be declared using the emits option, and the emit function is exposed on the setup() context:

As with other properties of the setup() context, emit can safely be destructured:

The emits option also supports an object syntax, which allows us to perform runtime validation of the payload of the emitted events:

If you are using TypeScript with <script setup> , it’s also possible to declare emitted events using pure type annotations:

Although optional, it is recommended to define all emitted events in order to better document how a component should work. It also allows Vue to exclude known listeners from fallthrough attributes, avoiding edge cases caused by DOM events manually dispatched by 3rd party code.

If a native event (e.g., click ) is defined in the emits option, the listener will now only listen to component-emitted click events and no longer respond to native click events.

Events Validation #

Similar to prop type validation, an emitted event can be validated if it is defined with the object syntax instead of the array syntax.

To add validation, the event is assigned a function that receives the arguments passed to the this.$emit emit call and returns a boolean to indicate whether the event is valid or not.

Usage with v-model #

Custom events can also be used to create custom inputs that work with v-model . Let’s revisit how v-model is used on a native element:

Under the hood, the template compiler expands v-model to the more verbose equivalent for us. So the above code does the same as the following:

When used on a component, v-model instead expands to this:

For this to actually work though, the <CustomInput> component must do two things:

Input подлагивает когда использую emit во vue

I want to add in the form the possibility to retrieve information on country, post code, city etc. by entering the address. I found a tutorial for doing this and I wanted to adapt the code to my needs, but the main problem is that this code doesn’t seem to work, at least for me.

Basically when I look for an address it should automatically fill in all the other fields, but nothing happens. Google Geocoding works and making various consoles.log I can retrieve the information I need, the problem is that the various inputs are not filled.

This is the complete code I am using in a .vue view for testing.

I have recently approached vue and I cannot understand what the problem is, reasoning I believe that I cannot identify which fields to update, but I have no errors, so debugging is even more complex.

Vue 3, $ emit никогда не срабатывает

Вы должны импортировать дочерний компонент в родительский компонент и использовать его вместо обычного тега div .

Я поделюсь с вами примерами для достижения эмиссии в Vue 3 с помощью <script setup> и Composition API. Я настоятельно рекомендую использовать <script setup , если вы собираетесь использовать Composition API в однофайловом компоненте. Однако выбор за вами.

Вы должны импортировать этот дочерний компонент в родительский. И не переименовывайте его в исходный тег html .vue3. Вам лучше использовать Composition API.

Три антипаттерна, которые следует избегать в Vue.js

Vue.js, вероятно, одна из самых приятных библиотек Javascript для frontend разработки. У него интуитивно понятный API, он быстрый, простой в использовании и гибкий. Однако наряду с гибкостью, некоторые разработчики часто попадают в небольшие ловушки, которые могут отрицательно сказаться на производительности приложения или долгосрочном обслуживании.

Итак, давайте углубимся в детали и посмотрим, каких распространенных ошибок следует избегать при разработке с помощью Vue.js.

Сайд-эффекты внутри вычисляемых свойств

Вычисляемые свойства в Vue.js — очень удобный способ управлять состоянием, которое зависит от другого состояния. Вычисляемые свойства следует использовать только для отображения состояния, которое зависит от другого состояния. Если вы обнаружите, что вызываете другие методы или назначаете другие свойства внутри computed, то, скорее всего, вы делаете что-то неправильно. Возьмем пример:

Если мы попытаемся отобразить массив и reversedArray , вы заметите, что оба массива имеют одинаковые значения.

original array: [ 3, 2, 1 ] computed array: [ 3, 2, 1 ]

Вычисляемое свойство reversedArray изменило исходное свойство массива из-за обратной функции. Это довольно простой пример, который приводит к неожиданному поведению. Давайте посмотрим на другой пример:

Предположим, у нас есть компонент, который отображает подробную информацию о цене заказа.

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

Теперь предположим, что в очень редком случае, мы хотим предоставить кому то из наших клиентов дополнительную скидку 10%. У нас может возникнуть соблазн изменить заказ и увеличить его скидку.

Однако это приведет к довольно серьезной ошибке.

Антипаттерны vue.js

Антипаттерны vue.js

Что на самом деле происходит в этом случае, так это то, что наше вычисляемое свойство «пересчитывается» каждый раз в бесконечном цикле. Мы меняем скидку, вычисляемое свойство выбирает это изменение, пересчитывает эту сумму и возвращает событие. Скидка снова увеличивается, что вызывает повторный вычисляемый пересчет и так далее до бесконечности.

Вы могли подумать, что в реальном приложении сделать такую ошибку невозможно, но так ли это? Наш сценарий (если бы это произошло) было бы очень сложно отладить или отследить, потому что он требует «особого клиента», который может появляться только один раз на каждые 1000 заказов.

Мутация вложенных props

Иногда может возникнуть соблазн отредактировать свойство в props, которое является объектом или массивом, потому что это «легко» сделать. Но разве это лучше всего? Давайте посмотрим на пример

У нас есть компонент Product.vue , который отображает название продукта, цену и наличие на складе. Он также содержит кнопку для добавления товара в корзину. При нажатии на кнопку может возникнуть желание напрямую уменьшить свойство product.stock . Это легко сделать. Однако это может создать несколько проблем:

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

Давайте предположим гипотетический случай, когда другой разработчик впервые просматривает код и видит родительский компонент.

Читать:
Как распечатать отдельную страницу в ворде

У разработчика может появиться мысль. Что ж, я должен уменьшить запас внутри метода addProductToCart . Тем самым мы вносим небольшую ошибку: теперь, если мы нажимаем кнопку, количество уменьшается на 2 вместо 1.

Представьте, что это особый случай, когда такая проверка проводится на наличие специальных товаров/скидок, и этот код попадает в производственную среду. Мы можем закончить тем, что пользователи будут покупать 2 продукта вместо 1.

Если это вас не убеждает, давайте предположим другой сценарий. Возьмем, к примеру, пользовательскую форму. Мы передаем user в качестве prop и хотим изменить его адрес электронной почты и имя. Код ниже может показаться «правильным»

Можно легко повесить v-model на user . VueJS позволяет это. Так почему бы не сделать это?

  • Что делать, если у нас есть требование добавить кнопку «Отмена» и отменить введенные изменения?
  • Что, если вызов нашего сервера завершится неудачно. Как нам отменить изменения для пользователя?
  • Действительно ли мы хотим отображать измененный адрес электронной почты и имя в родительском компоненте перед сохранением этих изменений?

Простое решение может заключаться в том, чтобы клонировать пользователя перед отправкой его в качестве входных данных (props).

Хотя это может сработать, это всего лишь способ решения реальной проблемы. Наша форма UserForm должна иметь собственное локальное состояние. Вот что мы можем сделать.

Хотя приведенный выше код определенно кажется более подробным, он позволяет избежать описанных выше проблем. Мы следим за изменениями свойств пользователя, а затем копируем их в form в data . Это позволяет нам иметь индивидуальное состояние для формы и:

  • Отменить изменения, переназначив форму this.form =
  • Иметь изолированное состояние для формы
  • Не влиять на родителя, если мы не хотим
  • Контролировать, когда мы сохраняем изменения

Прямой доступ к родительским компонентам

Доступ и выполнение операций с другими компонентами, кроме самого компонента, может привести к несоответствиям, ошибкам, странному поведению у связанных компонентов.

Мы рассмотрим пример с раскрывающимся списком. Предположим, у нас есть раскрывающееся родительское и раскрывающееся дочернее меню. Когда пользователь выбирает определенный вариант, мы хотим закрыть раскрывающееся меню, которое отображается/скрывается в родительском раскрывающемся списке. Давайте посмотрим на пример

Обратите внимание на метод selectOption . Хотя это случается очень редко, у некоторых людей возникнет желание получить доступ к $parent напрямую, потому что это просто. Код будет работать нормально на первый взгляд, но что, если:

  • Мы меняем свойство showMenu или selectedOption ? Раскрывающийся список не закроется, и ни один из вариантов не будет выбран;
  • Мы захотим добавить переход в выпадающее меню.

Код снова завершится ошибкой, потому что элемент $parent изменился. Родительский элемент dropdown-menu больше не раскрывающийся компонент, а transition компонент.

Принцип Props down, events up будет правильным подходом. При данном подходе дочерний компонент должен получать от родителя данные, котороые он не может менять и список родительских событий, которые он может вызвать.

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

Заключение

Самый короткий код — не всегда лучший, а «простые и быстрые» способы часто имеют недостатки. Каждый язык программирования, проект или фреймворк требует терпения и времени, чтобы правильно их использовать. То же самое и для Vue. Пишите код внимательно и терпеливо.

Изменение данных компонента с помощью emit Vue.js

Изменение данных компонента с помощью emit Vue.js

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

Установленный Node.js версии 10.x и выше. Вы можете проверить это, выполнив в терминале / командной строке команду, приведенную ниже:

Фреймворк VUE JS: быстрый старт

Получите бесплатный курс и узнайте, как создать веб-приложение на трендовой Frontend-технологии VUE JS с полного нуля

Редактор кода — я настоятельно рекомендую Visual Studio Code

Последнюю версию Vue, установленную на вашем компьютере

Vue CLI 3.0. Для этого сначала удалите старую версию CLI:

Затем установите новую:

Скачать стартовый проект Vue можно здесь

Распакуйте загруженный проект

Перейдите в разархивированный файл и выполните приведенную ниже команду, чтобы обновить все зависимости:

Передача данных через компоненты

Чтобы передать значения данных из родительских компонентов (например, app.vue) в дочерние (например, вложенные компоненты) внутри компонента приложения, Vue.js предоставляет нам платформу, называемую props. Props можно назвать пользовательскими атрибутами, которые можно зарегистрировать в компоненте, что позволяет определять данные в родительском компоненте, присваивать ему значение, а затем передавать значение в атрибут prop, на который затем можно ссылаться в дочерних компонентах.

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

Демонстрация

Мы рассмотрим процесс отправки событий из дочернего компонента, настроим прослушивание родительского компонента для передачи данных из дочернего компонента и, наконец, обновим значение данных.

Если вы следовали этому руководству с самого начала, вы скачали и открыли стартовый проект в VS Code. Проект является законченным, полным кодом к этому посту.

Причина, по которой этот проект является стартовым, заключается в том, что вы можете поэкспериментировать с концепцией prop, прежде чем начать знакомство с процессом.

Input подлагивает когда использую emit во vue

Vue 3, $ emit никогда не срабатывает

Slow inputs with Vue and Vue Material

I’m using VueJs 2.0 with Vue Material. I’m rendering a table with quite a few rows that contains multiple input fields and/or select fields (VueMaterial components).

When entering data into the inputs the components becomes quite slow. Here is a live demo on JSFiddle to better demonstrate the issue.

Try keeping a letter in when typing in the text input. With more rows even normal typing gets quite slow.

Any idea how to fix this?

3 Answers 3

It seems the problem is with Vue-Material. There is already a bug logged for this. https://github.com/marcosmoura/vue-material/issues/544

Seems like removing the second select box eases things up (see an updated demo).

Do you really need two identical select boxes?

a long time has passed but I think I have found a solution to make it a little better. First you need to fork the repo otherwise you will need to create pull requests to the official repo that is more or less abandoned. Once created the fork just open:

Go to line 41 and remove:

I don’t understand why this, I think they wanted to cache the list in some way but this just cause to cycle options twice making the component heavier. Especially with a lot of options.

I tested the component in several way and it seems to work fine now.

To be sincere I had to apply other fixes to make it work properly but not related to this topic.

Unfortunately the repo is abandoned, it is just code to fork to save some time but needs to be maintained and improved.

1. (Deep) Object Watchers

2. Ограничение реактивности через Object.freeze

5. Применение IntersectionObserver

Input подлагивает когда использую emit во vue

I want to add in the form the possibility to retrieve information on country, post code, city etc. by entering the address. I found a tutorial for doing this and I wanted to adapt the code to my needs, but the main problem is that this code doesn’t seem to work, at least for me.

Basically when I look for an address it should automatically fill in all the other fields, but nothing happens. Google Geocoding works and making various consoles.log I can retrieve the information I need, the problem is that the various inputs are not filled.

This is the complete code I am using in a .vue view for testing.

I have recently approached vue and I cannot understand what the problem is, reasoning I believe that I cannot identify which fields to update, but I have no errors, so debugging is even more complex.

Есть много способов сделать это: Vue 3 и взаимодействие компонентов

composable (composition API)

state manager (Vuex/Pinia)

Взаимодействие компонентов напрямую через Props/Emits

Взаимодействие компонентов напрямую через Provide/Inject

Vuex/Pinia (state managers).

Взаимодействие компонентов напрямую через Vuex/Pinia

Взаимодействие компонентов напрямую через Vuex/Pinia + Props/Emits

Взаимодействие через Props/Emits (примитивы)
Прямой props и emits
Writable computed
Provide/Inject
Взаимодействие через Props/Emits (объекты)
Прямой props и emit
Writable computed
Watch

[Vue warn]: Maximum recursive updates exceeded in component <Repl>. This means you have a reactive effect that is mutating its own dependencies and thus recursively triggering itself. Possible sources include component template, render function, updated hook or watcher source function.

Composable подход

Debouncing User Input with Vue: Delay the input event until the user stops typing

Portrait of me, Lukas HermannLukas Hermann

  • HTML
  • JS
  • Vue

Sometimes I want to persist user input to the server without the need for “Submit” or “Save” buttons. The user types into the text field and the app takes care of everything else without any further necessary action.

So-called “debouncing” can achieve this by waiting until the user stopped typing before sending the HTTP request to the server. This article shows how I achieved this with a handy custom Vue component.

# The Problem

I was working on my app stagetimer.io. It allows multiple participants to connect with their devices to view the same countdown timer. Each user can enter their name into a field so the controller can see who is connected. The app saves the name as it is typed, but the server can also update it. This posed two problems:

  1. Every keystroke fires an input event. Therefore it is necessary to debounce this event, that is, wait until the user stopped typing before saving it to the server, so it doesn’t trigger too many HTTP requests.
  2. A server response can also update the text of the input field. But while the user is typing it is relevant to prevent updating the value so the user doesn’t experience “jumping” of the text.
# The Solution

This Vue component solves both problems. It is designed to be used as a drop-in replacement for the native <input> tag.

First, here is the component in full. Underneath I explain what each part does and how it works.

# 1–7 <template>

<input> is the only HTML element inside the template. I use a copy of the passed value prop, called internalValue , for reasons explained later. The type prop is just a passthrough, more can be added as required.

I am not using v-model to keep track of user input with the touched variable, see line 31.

# 13–16 Props

Besides the mandatory value prop I am giving default values to all others. This way I can safely omit them when using the component.

# 17–22 Data

I could use value directly and pass it to the input element, but this can lead to a race condition. If the app sends the value to the server it is common for it to respond with the same value causing an app update. Had the user continued typing, this update would reset the value removing the last typed characters. Therefore I added a decoupled internalValue to keep track of user input with the touched variable.

# 23–27 Watcher

Here I am watching the value prop for changes and update the internalValue only if the user hasn’t touched the input, implying he hasn’t typed anything else in the meantime.

# 29–32 updateInternalValue() Method

Every keystroke triggers this method. With touched = true I can keep track of it. It then calls the updateValue() method with that magic debouncing mechanic.

# 33–37 updateValue() Method

This method is the heart of the entire component. It uses lodash’s debounce method. updateValue() can be called multiple times with the same parameters and only executes the callback function the delay of 600 ms has passed after the last call.

It is essential to use an anonymous function here, not an arrow function, to preserve Vue’s this context.

I set touched = false once the callback is executed, signifying that at this time the value is passed to the parent component. Changes to the value prop can now be updated safely to my internalValue until the user starts typing again.

Afterward, I emit two events. The input event enables the use of v-model with this component, and the update:value event ensures that Vue’s two-way binding value.sync also works.

Note: This guide is for Vue version 2. For Vue 3 it is necessary to rename the prop value to modelValue , see https://v3.vuejs.org/guide/migration/v-model.html#v-model.

Liked this article?

© Lukas Hermann · Brenzstrasse 6 · 74405 Gaildorf · Germany

Related Posts