контекст this в обработчике дочернего события функционального компонента - PullRequest
0 голосов
/ 12 ноября 2018

Я пытаюсь создать пользовательские обработчики событий для дочерних компонентов / элементов функционального компонента.Проблема в том, что при использовании функции render() для создания дочерних компонентов я не могу получить доступ к их контексту this.

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

const Aggregate = {
    functional: true,
    props: {
        value: Object // to work with v-model
    },
    render: function(createElement, context){
        const template = []
        const inputHandler = function(value, prop){
            const data = Object.assign({}, context.props.value, { [prop]: value })
            console.log(context.props.value)
            console.log(data)
            this.$emit('input', data)
        }
        for (const prop of Object.keys(context.props.value)){
            const child = createElement('input', {
                props: {
                    value: context.props[prop]
                },
                on: {
                    input: function(event){
                        // 'this' is not binded here - it is undefined,
                        // hence the inputHandler() function is
                        // rising an error
                        inputHandler.apply(this, [event.target.value, prop])
                    }
                }
            })
            template.push(child)
        }
        return template
    }
}

Isможно ли получить доступ к контексту this для vnode, когда создаешь обработчик событий таким образом?

PS Информация о примере использования: я хочу реализовать компонент, который автоматически генерирует элементы <input> для ресурса и использует дваспособ связывания через директиву v-model.Я также хочу использовать его в <table>, где потребуется обтекание в <td>, поэтому я сделал компонент функциональным.

1 Ответ

0 голосов
/ 12 ноября 2018

Функциональные компоненты не имеют "this", потому что для них нет экземпляра Vue. Это делает их легкими.

Это также означает, что генерировать события из них немного сложнее, поскольку вам нужно самостоятельно реализовать логику Vue.

Отсутствие экземпляра не означает, что вы не можете событий, вместо этого вам нужно вручную проанализировать context.listeners и вызвать обработчик событий вручную. В случае v-model вам необходимо вызвать input слушатель:

const Aggregate = {
    functional: true,
    props: {
        value: Object // to work with v-model
    },
    render: function(createElement, context){
        const template = []
        const inputHandler = function(value, prop, handler){
            const data = Object.assign({}, context.props.value, { [prop]: value })
            console.log(context.props.value)
            console.log(data)
            // Call handler directly instead of using this.$emit
            handler(data)
        }
        for (const prop of Object.keys(context.props.value)){
        console.log(context.props.value, prop)
            const child = createElement('input', {
                // Small bug fixes in the following section:
                domProps: {
                    value: context.props.value[prop]
                },
                // End bug fixes
                on: {
                    input: function(event){
                        // pass `context.listeners.input` instead of binding here
                        inputHandler(event.target.value, prop, context.listeners.input)
                    }
                }
            })
            template.push(child)
        }
        return template
    }
}


new Vue({
  el: "#app",
  components: {
  	Aggregate
  },
  data: {
    test: {
    	key1: "val1",
    	key2: "val2",
      
    }
  },
})
<!-- development version, includes helpful console warnings -->



  
  {{ test }}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...