Как сделать правильно управляемый и реактивный компонент с помощью JSX в Vue - PullRequest
1 голос
/ 10 июля 2019

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

Ниже приведен простой эскиз кода и двух компонентов:

TextInput.js

export default {
    name: "TextInput",

    props: {
        value: [String, Number]
    },

    methods: {
        inputted(e) {
            this.$emit('input', e);
        }
    },

    render() {
        return (
            <input 
                value={this.value}
                onInput={(e) => this.inputted(e)}
            />
        );
    }
}

Example.js

export default {
    data() {
        return {
            depositAmount: ""
        };
    },

    methods: {
        handleInput(newValue) {
            let parts = newValue.match(/^(\d+)?(\.)?(\d{0,6})?$/);
            if (parts !== null) {
                this.depositAmount = parts[0];
            }
        },
    },

    render() {
        return (
            <TextInput
                value={this.depositAmount}
                onInput={(e) => this.handleInput(e.target.value)}
            />
        );
    }
}

Мне кажется, что жизненный цикл здесь должен быть примерно следующим:

  • пользователь вводит строку
  • onInput срабатывает на базе <input> тег
  • onInput вызывается TextInput
  • handleInput вызывается и проверяет всю строку на соответствие регулярному выражению
  • , еслиновый ввод действителен, depositAmount обновляется, если ничего не происходит
  • value реквизит TextInput установлен на depositAmount
  • value базы *Для тега 1038 * установлено значение value из TextInput (что составляет depositAmount)

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

Это все хорошо, когда ввод действителен.Однако, когда оно недопустимо, depositAmount не меняет , но значение базового <input> элемента действительно изменяется .

Как можноЯ делаю значение ввода 1: 1 с данными родителя, даже когда вход обновляется, но данные родителя не обновляются?

Рабочий пример. Как вы можете видеть<input>, который отключен и просто принимает значение проверенного и очищенного ввода через depositAmount, работает правильно.Но <input>, с которым взаимодействуют и вводятся, игнорирует его контролируемое значение и просто отражает то, что ввел пользователь.


PSEUDO-SOLUTION

Единственный способ, которым яЧтобы решить эту проблему, нужно добавить this.$forceUpdate() в обработчик корневых событий

TextInput.js

...
methods: {
    inputted(e) {
        this.$emit('input', e);
        this.$forceUpdate();
    }
}
...

Я говорю, что это "псевдо" решение, потому что пока оно решает проблему ивынуждает ввод всегда принимать значение, которое он передает от своего родителя, я остаюсь неудовлетворенным, когда сожалею, используя $forceUpdate, когда мне кажется, что это должна быть ситуация, когда "это просто работает".

Такхотя есть быстрое исправление, я оставляю это открытым, так как мне бы хотелось услышать реальное решение или услышать то, что я здесь не понимаю, что требует $forceUpdate.Похоже, что расхождение Vue должно заметить, что реквизит отличается от фактического значения элемента <input>, даже если они должны быть связаны.

...