У меня есть вычисленное свойство, которое я использую как v-model
на входе. Я написал это так, чтобы получить реактивность - это вызывает мое действие setText
Vuex, которое я затем могу получить с помощью моего получателя text
. Это выглядит так:
text: {
get() {
return this.text;
},
set(value) {
this.setText(value);
},
},
и я использую его для ввода вот так:
<input class = "input" type = "text" v-model = "text" />
Это хорошо работает. Теперь я поместил рассматриваемый input
в отдельный компонент, который использую. Это означает, что я должен передать v-модель text
в качестве реквизита, что я и делаю с :model.sync
, например:
<myInput :model.sync = "text"/>
а в компоненте myInput
я использую такие реквизиты:
<input class = "input" id = "search-order" type = "text" :value = "model" @input = "$emit('update:model', $event)">
Но, похоже, это вообще не работает, всякий раз, когда я набираю ввод, ввод говорит: [object InputEvent]
, и если я пытаюсь увидеть и значение model
, это {isTrusted: true}
. Я предполагаю, что это из-за геттеров и сеттеров, которые у меня есть в моем вычисляемом свойстве. Как передать их дочернему компоненту?
Вот это да. Спасибо чувак!
Вместо использования модификатора .sync
вы можете поддерживать директиву v-model
в своем пользовательском компоненте. v-model
- это синтаксический сахар для опоры value
и события input
.
Для поддержки v-model
просто убедитесь, что ваш пользовательский компонент имеет опору value
и генерирует событие input
с новым значением: this.$emit('input', event.target.value)
.
Вот пример компонента <BaseInput>
, который я использую, он написан на TypeScript:
<template>
<input
:type = "type"
:value = "value"
class = "input"
v-on = "listeners"
>
</template>
<script lang = "ts">
import Vue from 'vue'
export default Vue.extend({
name: 'BaseInput',
props: {
type: {
type: String,
default: 'text',
},
value: {
type: [String, Number],
default: '',
},
lazy: {
type: Boolean,
default: false,
},
number: {
type: Boolean,
default: false,
},
trim: {
type: Boolean,
default: false,
},
},
computed: {
modelEvent(): string {
return this.lazy ? 'change' : 'input'
},
parseModel(): (value: string) => string | number {
return (value: string) => {
if (this.type === 'number' || this.number) {
const res = Number.parseFloat(value)
// If the value cannot be parsed with parseFloat(),
// then the original value is returned.
return Number.isNaN(res) ? value : res
} else if (this.trim) {
return value.trim()
}
return value
}
},
listeners(): Record<string, Function | Function[]> {
return {
...this.$listeners,
[this.modelEvent]: (event: HTMLElementEvent<HTMLInputElement>) =>
this.$emit(this.modelEvent, this.parseModel(event.target.value)),
}
},
})
</script>
Вы можете использовать это так:
<BaseInput v-model = "text" />
$emit('update:model', $event.target.value)