De vuelta en vue 2, solía llamar a render() así:
export default { mounted(){ ... }, render(){ ... }, methods(){ ... } }Ahora estoy tratando de hacer lo mismo con Vue 3 y la API de composición. Esto es lo que probé:
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() } } Esto no parece devolver nada en mi plantilla. Creo que no estoy llamando a la función de render de la manera correcta. ¿Alguien puede ayudarme a entender cómo usarlo?
Según tengo entendido, h() es una forma abreviada para crear los vnodes y aceptar 3 parámetros.
h( tag name, props/attributes, array of children ) Según tengo entendido, en create_canvas está intentando crear un div que contiene una class y inline styles como accesorios/atributos y estamos creando un canvas como elemento secundario de este div vnode. Por lo tanto, en lugar de devolver el vNode directamente desde setup(), debería devolver una función de representación que devuelve un 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 || [])) } ✅ } }Primero, no está "llamando" a la función de renderizado, solo lo está declarando (Vue lo está llamando al renderizar)
En la API de composición, solo necesita devolver la función de renderizado desde 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) } } Después de aplicar este conocimiento en su propio código, diría que la última línea de setup no debe ser render() sino return render() (porque la función render() en sí misma devuelve la función "render" real)
En JS, las funciones se tratan como datos: puede almacenarlas en variables y devolverlas desde las funciones. Cuando la función se almacena o se devuelve como resultado de otra función, no se ejecuta inmediatamente, solo se crea. El que llama a la función de "fábrica" (en este caso, la función de fábrica es setup() y la persona que llama es Vue) puede almacenar la referencia a la función devuelta y decide cuándo llamarla
El gancho onMounted de la API de composición de Vue funciona de manera muy similar. Está llamando a onMounted() pasando una función recién creada como argumento. onMounted almacena la referencia a la función en algún lugar para que Vue pueda llamarla más tarde.
El punto es que no importa que en setup() onMounted() se ejecute primero y su función de representación se devuelva como una última declaración de setup . Porque Vue decide cuándo llamarlos "a veces más tarde". Y es razonable esperar que Vue llame a su función de representación al menos una vez antes de llamar a una función pasada a onMounted() (porque el componente no se puede montar antes de que se represente)