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