Vue.js / JSX: динамическое имя события

1

Я пишу компонент Vue.js. Компонент отображает элемент <input>. Слушатель событий прослушивает либо change либо input события, в соответствии со значением проп.

Как написать функцию рендеринга с JSX?

{
  props: {
    lazy: Boolean,
  },
  render(h) {
    const bindEvent = this.lazy? 'change' : 'input'
    return h('input', {
      attrs: {
        type: 'text',
      },
      on: {
        [bindEvent]: e => this.$emit('update', e.target.value)
      },
    })
  },
}

Я хочу написать что-то вроде этого:

render(h) {
  const bindEvent = this.lazy? 'change' : 'input'
  return <input
    type='text'
    on={{ [bindEvent]: e => this.$emit('update', e.target.value) }}
  />
}
Теги:
vue.js

2 ответа

0
Лучший ответ

Решение 1. Добавление слушателя события к каждому событию

render() {
  const eventHandler = name =>
    (this.bindEvent === name)? e => this.$emit('update', e.target.value)
    : () => {}
  return <input
    type='text'
    onChange={eventHandler('change')}
    onInput={eventHandler('input')}
  />
}

Решение 2. Добавление прослушивателя событий в VNode

render() {
  const eventHandler = name =>
    (this.bindEvent === name)? e => this.$emit('update', e.target.value)
    : () => {}
  const vNode= <input type='text' />
  vNode.data.on = { [this.bindEvent]: e => this.$emit('update', e.target.value) }
  return vNode
}
0

Ты почти там. Просто немного подправить, вот так.

<input
  type="text"
  v-on="{ [bindEvent]: e => this.$emit('update', e.target.value) }"
/>

Смотрите рабочую реализацию.

  • 0
    Конечно, это работает для шаблонов, но не для JSX в функции рендеринга. Он компилируется в "directives": [{ name: "on", value: { [this.bindEvent]: e => { this.bindValue(e.target.value); } } }] . И консоль: [Vue warn]: Failed to resolve directive: on

Ещё вопросы

Сообщество Overcoder
Наверх
Меню