vue.js - 功能组件的子事件处理程序中的“this”上下文

标签 vue.js vuejs2

我正在尝试为功能组件的子组件/元素创建自定义事件处理程序。问题是当使用 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
    }
}

是否可以访问this vnode 的上下文,当以这种方式创建事件处理程序时?

附言用例信息:我想实现一个自动生成 <input> 的组件资源的元素,并通过 v-model 使用双向绑定(bind)指示。我也想在 <table> 中使用它包装在 <td> 中将是必需的,因此我使组件起作用。

最佳答案

函数式组件没有“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 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<div id="app">
  <aggregate  v-model="test"></aggregate>
  <pre>{{ test }}</pre>
  <button @click="test = {...test, ping: 'pong'}">Add key</button>
</div>

关于vue.js - 功能组件的子事件处理程序中的“this”上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53264452/

相关文章:

Vue.js 滚动到同一路线的页面顶部

javascript - Vue如何正确遍历列表?

vuejs2 - 如何使用 nuxtjs/pwa 实现后台同步?

javascript - 组件内 Navigation Guard 回调不起作用 : Nuxt JS and `beforeRouteEnter`

javascript - 如何使用 Vue.js 在单击时更新特定的子元素?

javascript - Vuex 中的 Action 完成后从商店调用组件函数

javascript - VueJS 类绑定(bind)无法正常工作

vue.js - 在 vue.js 中过滤 2 个或更多类别

javascript - vue.js - v-for 中动态生成的组件未正确更新绑定(bind)属性

javascript - 在本地组件 vuejs 中访问 Prop 值