Vue: Добавить пользовательские модификаторы v-модели

Созданный на 13 сент. 2016  ·  52Комментарии  ·  Источник: vuejs/vue

У нас есть .lazy , .number , .trim и .undef уже в пути.

Кроме .lazy все они работают как двухсторонние фильтры.

Поскольку 2.0 не поддерживает двухсторонние фильтры, возможно, должен быть новый API для добавления пользовательских модификаторов v-модели для удовлетворения той же потребности.

feature request

Самый полезный комментарий

Есть ли шанс, что мы сможем снова открыть этот вопрос? Обычным случаем использования для меня является необходимость автоматического форматирования данных в поле по мере их ввода. Что-то вроде «101216» и превращения его в «10/12/16». Возможность создать пользовательский модификатор v-model значительно упростила бы мой код, поскольку я мог написать v-model.date вместо создания собственного компонента ввода с реквизитами и событиями.

Все 52 Комментарий

Вычисляемые свойства @posva нельзя использовать повторно.

Почти все можно повторно использовать через миксин.
Вы можете использовать функцию, которая генерирует миксин. Таким образом, вы можете связать
вычисляемое свойство динамически. Я не могу сейчас поставить этот пример на скрипку
но я бы сделал это как можно скорее.
Тем не менее, я согласен, что это очень распространенный вариант использования входных данных.
применены преобразования. Надлежащий API или хотя бы объяснение по
руководство необходимо

Вт, 13 сентября 2016 г., 18:48 Франсиско Лоуренсо, уведомления@github.com
написал:

Вычисленные свойства @posva https://github.com/posva нельзя использовать повторно.


Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/vuejs/vue/issues/3666#issuecomment -246746524 или отключить звук
нить
https://github.com/notifications/unsubscribe-auth/AAoicf33lCvETQc9LBQ5GGZ93ExPcLS_ks5qptPegaJpZM4J7vQ0
.

Почти все можно повторно использовать через миксин.
Вы можете использовать функцию, которая генерирует миксин. Таким образом, вы можете связать
вычисляемое свойство динамически. Я не могу сейчас поставить этот пример на скрипку
но я бы сделал это как можно скорее.
Тем не менее, я согласен, что это очень распространенный вариант использования входных данных.
применены преобразования. Надлежащий API или хотя бы объяснение по
руководство необходимо

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

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

InputCustom.js

define(function () {
  return Vue.extend({
    data: function () {
      return {
        focused: false
      };
    },
    template: '<input @focus="onFocus" @blur="onBlur" @input="onInput" @change="setDisplayValue">',
    props: ['value'],
    watch: {
      value: function () {
        if (!this.focused) {
          this.setDisplayValue();
        }
      }
    },
    mounted: function () {
      this.setDisplayValue();
    },
    methods: {
      onInput: function () {
        this.$emit('input', this.parse(this.$el.value));
      },
      onFocus: function () {
        this.focused = true;
      },
      onBlur: function () {
        this.focused = false;
        this.setDisplayValue();
      },
      setDisplayValue: function () {
        this.$el.value = this.format(this.value);
      }
    }
  });
});

InputText.js

define(['js/InputCustom'], function (InputCustom) {
  return InputCustom.extend({
    methods: {
      parse: function (val) {
        val = val.trim();
        return val === '' ? null : val;
      },
      format: function (val) {
        return val === null ? '' : val;
      }
    }
  });
});

На мой взгляд, такой подход очень удобен, и я решил вообще не использовать модификаторы v-model, включая .lazy .

Для более настраиваемых вариантов использования, которые не могут поддерживать встроенные модификаторы, рекомендуемым подходом является упомянутый @ecmel . Мы задокументируем это более подробно в официальном руководстве.

Идея этого предложения функции состоит в том, чтобы воспользоваться преимуществами существующей директивы v-model , которая уже работает с каждым элементом input . Чтобы сохранить работу по написанию _InputCustom.js_ в каждом проекте, потому что это уже было сделано в v-model , достаточно написать эквивалент _InputText.js_ в пользовательском модификаторе, который содержит всю логику, необходимую для модифицироваться чаще всего. Тот факт, что v-model уже поставляется с модификаторами, доказывает, что это интуитивный и желательный шаблон. Вполне естественно облегчить создание пользовательских модификаторов, чтобы сэкономить работу по созданию пользовательских элементов и необходимости вручную выполнять привязку dom/model.

Если это имеет смысл с точки зрения API, было бы интересно узнать, какие технические ограничения привели к решению не реализовывать эту функцию.

Есть ли шанс, что мы сможем снова открыть этот вопрос? Обычным случаем использования для меня является необходимость автоматического форматирования данных в поле по мере их ввода. Что-то вроде «101216» и превращения его в «10/12/16». Возможность создать пользовательский модификатор v-model значительно упростила бы мой код, поскольку я мог написать v-model.date вместо создания собственного компонента ввода с реквизитами и событиями.

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

По крайней мере, нам нужен модификатор undef .

Я согласен, что этот вопрос должен быть вновь открыт. Не уверен, что undef должен был делать, но мне нужен модификатор v-model , который устанавливает мою переменную в null в случае, если усеченное значение ввода является пустой строкой.

Я хотел бы иметь возможность сделать это сам простым способом.

Функциональность, более избыточная, чем эта, была добавлена, например, с помощью https://github.com/vuejs/vue/issues/5194 . Со стороны кажется, что Vue медленно идет на компромисс с некоторыми из своих принципов в пользу соглашений и практик, продвигаемых сообществом реагирования. Немного отклоняясь от качеств, которые выделяли его в первую очередь. Было бы интересно узнать, является ли это сознательным решением с намерением упростить миграцию из реакции или просто совпадение.

Написание пользовательских компонентов — это хорошо, но если вы хотите использовать сторонний пользовательский компонент, такой как https://github.com/text-mask/text-mask/tree/master/vue#readme , нет прямого способа дезинфицировать замаскированный ввод значений модели, за исключением использования вычисляемых свойств.

Итак, я просто хочу использовать стандартное поле ввода [тип = дата] HTML для редактирования типа даты в моей модели, и эта удивительно мощная и расширяемая структура не может сделать это из коробки? Не удается прочитать дату в поле, перезапишите мою дату строкой в ​​​​моих данных после того, как я выберу дату. Это решение может быть записано в две строки с двусторонними фильтрами или с модификатором.

Но лучшим решением было бы просто поддерживать его изначально, как это делается для флажка и другого стандартного поля ввода, почему «дата» особенная вещь?

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

Маскирование входных данных и анализ значения для использования приложением — очень распространенная практика, и создание некоторого «синтатического сахара», такого как v-model.lazy.currency="amount", было бы потрясающе!

1+ для пользовательских модификаторов.
У меня есть простой радио-вход со значениями true | false, которые оцениваются как строки. Но они мне нужны как логические значения. В этом случае вычисляемые свойства не будут умными, поскольку мне нужно повторно реализовать вычисляемое свойство для каждого радио-входа. Например, наличие 100 радиовходов приведет к 100 вычисляемым свойствам.

+1 за пользовательские модификаторы, но я согласен с tobei - input[type=date] должен работать автоматически.

+1 за пользовательские модификаторы.

Я родом из Angular, только начал с vue и увидел эту тему.

Я чувствую, что было бы действительно полезно иметь что-то вроде парсеров и форматтеров Angular, в том числе и во Vue. Если бы я мог сделать что-то вроде v-model.dateFormat и получить что-то вроде мм/дд/гггг, это было бы действительно здорово.

РЕДАКТИРОВАТЬ: похоже, он повторил то, что сказал @restored18 . +1 тебе тоже

+1 за пользовательские модификаторы v-модели.

В моем случае я перебираю несколько вложенных объектов, полученных в JSON, и использую один шаблон HTML (а не шаблон для каждого объекта). В этом случае я считаю, что вычисляемые свойства не работают?

В настоящее время я добавляю пользовательские методы преобразования между форматом сервера и форматом v-модели при извлечении и отправке данных, но мне бы хотелось что-то просто «встроенное», которому я мог бы передать функции.

+1 к этому. Он был доступен до 2.2. Вы можете получить доступ к собственности через,

this.$vnode.data.directives

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

+1 за это.

Пользовательские модификаторы v-модели были бы великолепны!

я тоже

+1 в 2018 тоже...

+1 На мой взгляд, это необходимая функция для DRY-кода. Сейчас мне нужно создать 10 наблюдателей, которые делают то же самое для формы с большим количеством входных данных. Пользовательский модификатор решит все.

+1 Я только запустил vue, и мне уже нужны такие двухсторонние фильтры...

+1 обязательно нужен

+1

Вы можете создавать подобные помощники для большинства случаев использования IMO.

@nickmessing , который не охватывает описанный здесь (действительно полезный) вариант использования, который представляет собой модификацию входного текста на месте. Если у вас есть поле ввода, которое вы хотите всегда форматировать как телефон, у вас будет <input v-model.phone="some_data"> . Когда пользователь вводил текст, он автоматически форматировал его.

Это кажется такой базовой функцией, и сейчас это сложнее, чем должно быть. Такое поведение уже существует во фреймворке, но по какой-то причине оно ограничено только кодом фреймворка. Мы хотим иметь возможность добавить пользовательский модификатор, который будет делать это, который можно будет повторно использовать в компонентах и ​​проектах, точно так же, как фильтры и директивы прямо сейчас.

@bbugh полностью согласен, у меня похожий случай с форматированием IBAN, и это был бы такой хороший и деклеративный способ просто поместить туда v-model.iban="payment.iban" ...

@franciscolourenco , возможно, кто-то мог бы обосновать, почему это не должно поддерживаться фреймворком, чтобы это стало более очевидным.

+1 за пользовательские модификаторы, существует множество вариантов использования этой функции.

В нашем приложении есть несколько различных входных данных для форматирования валют, мы всегда храним сумму в центах в модели, но отображаем правильно отформатированные суммы в долларах во входных данных (так что 123456 в модели отображается как 1234,56 доллара США) <input v-model.dollars="cents" />

Другим вариантом использования является очистка и удаление полей html для предотвращения атак XSS (модель хранит « A &amp; B », в то время как ввод показывает « A & B ») <input v-model.html="text" />

+1

+1

+1 за пользовательские модификаторы.
Я был очень удивлен, что не могу сделать что-то вроде v-model.trim.uppercase=...

+1

+1

+1

+1
Нативные модификаторы ввода v-model были бы отличной функцией. Как люди упоминают здесь, есть много вариантов использования. Мне нужны были модификаторы даты и валюты для всех проектов, над которыми я работал.

мы должны открыть вопрос здесь? https://github.com/vuejs/rfcs

у меня уже есть +1 к этому, но хочу кинуть заметку для людей, которым что-то нужно "сейчас"

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

могу поделиться примером, если кому нужно

Мы не реализовали это, потому что в этой, казалось бы, простой функции нужно учитывать множество моментов:

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

  • Что касается конфигурации времени выполнения, какой API мы должны предоставить для этого?

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

    • Причина, по которой у нас есть .number и .trim , заключается в том, что они на самом деле являются односторонними преобразованиями (применяются только при синхронизации значения DOM с данными компонента) и, таким образом, гарантированно стабилизируются.
  • Как должны вести себя пользовательские модификаторы, когда v-model используется в компоненте?

  • Как пользовательские модификаторы должны вести себя с нетекстовыми типами ввода, например, radio , checkbox и, самое главное, <select> ?

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

@rkingon В https://github.com/vuejs/vue/issues/3666#issuecomment -249583603 уже есть пример, но если ваш отличается/лучше, просто опубликуйте его. Это может быть полезно для новичков.

@Gotterbild я пропустил этот образец, но он слишком сложен в более поздних версиях Vue (это могло быть предварительно прозрачная поддержка компонентов)

вот очень простой, который у меня есть, который просто преобразует проценты в десятичные числа (т.е.: 4,5 -> 0,045) и наоборот (значение "просмотр" и значение "модель")

<template>
    <input type="number" v-on="listeners" v-model="innerValue">
</template>

<script>

    export default {
        props: ['value'],
        computed: {
            listeners () {
                const { input, ...listeners } = this.$listeners
                return listeners
            },
            innerValue: {
                get () {
                    return (this.value) ? `${(this.value * 100)}` : ''
                },
                set (_val) {
                    const val = (_val) ? (_val / 100) : ''
                    this.$emit('input', val)
                }
            }
        }
    }

</script>

это проще, чем выше, так как вам не нужно повторно указывать все фокус/размытие/и т. д.

@ yyx990803 спасибо, что предоставили дополнительную справочную информацию по этой теме.

для моих вариантов использования мне не «нужны» пользовательские модификаторы. просто с точки зрения потребителей было бы логично, если бы у vue был способ создать свой собственный. в основном это есть для всего, кроме модификаторов 😄

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

Я пришел сюда, потому что искал модификатор для преобразования строки в верхний регистр.
Я хотел создать его как v-model.uppercase="username"

В итоге я использовал пользовательскую директиву

Vue.directive('uppercase', {
    update (el) {
        el.value = el.value.toUpperCase()
    },
})

<input type="text" v-model="username" v-uppercase>

Пользовательских директив должно быть достаточно для альтернативы.
Или есть что-то, что возможно только с пользовательским модификатором v-model?

@Christhofernatalius, учитывая, что v-model - это просто директива, не могли бы вы исключить v-model в пользу пользовательской директивы? таким образом, вы не обновляете дважды?

@Christhofernatalius, учитывая, что v-model - это просто директива, не могли бы вы исключить v-model в пользу пользовательской директивы? таким образом, вы не обновляете дважды?

@rkingon Он обновляется дважды?
Итак, если я не использую v-модель, то мне нужно также добавить привязку и развязку для прослушивателя ввода и обновить значение имени пользователя?

РЕДАКТИРОВАТЬ: Разве использование вычислений с сеттером и геттером также не обновляется дважды?
РЕДАКТИРОВАТЬ 2: я попробовал консольный журнал наблюдателя и директивы, каждый из которых печатается только один раз для каждого нажатия клавиши.

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

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

два способа освежевать кота, приятно иметь варианты :)

Есть ли RFC для этого?

я так не думаю

Я мог бы создать его, но означает ли это просто добавление проблемы в этот репозиторий RFC или что-то еще?

https://github.com/vuejs/rfcs#what -the-process-is отвечает на ваш вопрос?

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

Vue.directive('number', {
  update: function(el, binding, vnode) {
    el.value = el.value.replace(/[^\d.]/g, '');
  },
});

Если вы добавите эту директиву (вместе с v-моделью) и наберете буквы очень быстро, каждое второе нажатие клавиши v-model будет рассинхронизировано с el.value . И поскольку вы не можете изменить объект привязки, который вы получаете, нет возможности «повторно реализовать» v-модель внутри этой директивы.

@jeankvd Я знаю, что это кажется излишним, но компонент-оболочка будет самым надежным (см. Пример выше).

компонент-оболочка также позволит вам «сделать больше». В вашем «числовом» примере в идеале v-модель фактически становится Number . В вашем подходе это все еще String .

Что делать, если вы хотите настроить пустое значение? Пустой строки? Нулевой? Неопределенный? -- вы можете передать реквизит для emptyValue и установить его как таковой.

Когда-то я выступал за это, но вскоре понял, что у модификаторов слишком много ограничений, и просто наличие компонента намного лучше (по крайней мере, imo).

Была ли эта страница полезной?
0 / 5 - 0 рейтинги