如何在Vue 3合成api中调用渲染函数?



在vue 2中,我曾经这样调用render():

export default {
mounted(){
...
},
render(){
...
},
methods(){
...
}
}

我现在正试图用Vue 3和合成api做同样的事情。下面是我的尝试:

export default {
...
setup(props, context){
...
const create_canvas = (h, id, props) => {
_id.value = id
_attrs.value = props.attrs
return () => h('div', {
class: `trading-vue-${id}`,
style: {
left: props.position.x + 'px',
top: props.position.y + 'px',
position: 'absolute',
}
}, [
h('canvas', Object.assign({
id: `${props.tv_id}-${id}-canvas`,
onmousemove: e => renderer.mousemove(e),
onmouseout: e => renderer.mouseout(e),
onmouseup: e => renderer.mouseup(e),
onmousedown: e => renderer.mousedown(e),
ref: 'canvas',
style: props.style,
}, props.attrs))
].concat(props.hs || []))
};
function render() {
const id = props.grid_id
const layout = props.layout.grids[id]
return () => create_canvas(h, `grid-${id}`, {
position: {
x: 0,
y: layout.offset || 0
},
attrs: {
width: layout.width,
height: layout.height,
overflow: 'hidden'
},
style: {
backgroundColor: props.colors.back
},
hs: [
h(Crosshair, Object.assign(
common_props(),
layer_events
)),
h(KeyboardListener, keyboard_events),
h(UxLayer, {
id,
tv_id: props.tv_id,
uxs: uxs.value,
colors: props.colors,
config: props.config,
updater: Math.random(),
onCustomEvent: emit_ux_event
})
].concat(get_overlays(h))
})
};
render()
}
}

这在我的模板中似乎没有返回任何东西。我认为我没有以正确的方式调用render函数。谁能帮我理解如何使用它?

根据我的理解,h()是创建vnodes并接受3个参数的简短形式。

h(
tag name,
props/attributes,
array of children
)

根据我的理解,在create_canvas中,您正在尝试创建一个包含classinline styles作为道具/属性的div,我们正在创建一个canvas作为这个divvnode的子节点。因此,与其直接从setup()返回vNode,它应该返回一个返回vNode的渲染函数。

export default {
props: {
// props will come here
},
setup(props) {
// render() { h(...) } ❌
return () => {
h('div', {
class: `trading-vue-${id}`,
style: {
left: props.position.x + 'px',
top: props.position.y + 'px',
position: 'absolute',
}
}, [
h('canvas', Object.assign({
id: `${props.tv_id}-${id}-canvas`,
onmousemove: e => renderer.mousemove(e),
onmouseout: e => renderer.mouseout(e),
onmouseup: e => renderer.mouseup(e),
onmousedown: e => renderer.mousedown(e),
ref: 'canvas',
style: props.style,
}, props.attrs))
].concat(props.hs || []))
} ✅
}
}

首先你不是在"打电话";渲染函数-你只是声明它(Vue在渲染时调用它)

在合成API中,你只需要从setup返回渲染函数

import { ref, h } from 'vue'
export default {
props: {
/* ... */
},
setup(props) {
const count = ref(1)
// return the render function
return () => h('div', props.msg + count.value)
}
}
在将这些知识应用于您自己的代码之后,我会说setup的最后一行不应该是render(),而是return render()(因为render()函数本身返回实际的"渲染")。函数)

在JS中函数被视为数据-你可以将它们存储在变量中并从函数中返回它们。当函数被存储或作为另一个函数的结果返回时,它不会立即执行——它只是被创建。给"工厂"打电话的人函数(在本例中,工厂函数是setup(),调用者是Vue)可以存储对返回函数的引用,并且决定何时调用它

Vue Composition API的onMounted钩子的工作原理非常相似。您正在调用onMounted(),并将新创建的函数作为参数传递。onMounted将对函数的引用存储在某个地方,以便Vue以后可以调用它。

关键是,在setup()中,onMounted()首先执行,您的渲染函数作为setup的最后一条语句返回并不重要。因为Vue决定何时调用它们"有时稍后"。我们可以合理地期望Vue在调用传递给onMounted()的函数之前至少调用一次渲染函数(因为组件在渲染之前不能挂载)

最新更新