Home > Enterprise >  How to call render functions in Vue 3 composition api?
How to call render functions in Vue 3 composition api?

Time:05-16

Back in vue 2 i used to call render() like that:

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

I'm now trying to do the same with Vue 3 and the composition api. Here is what i tried:

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`,
                    onm ousemove: e => renderer.mousemove(e),
                    onm ouseout: e => renderer.mouseout(e),
                    onm ouseup: e => renderer.mouseup(e),
                    onm ousedown: 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()
    }
}

This doesn't seem to return anything in my template. I think that i'm not calling the render function in the right way. Can anyone help me understanding how to use it?

CodePudding user response:

As per my understanding, h() is a short form to create the vnodes and accept 3 parameters.

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

As per my understanding, In create_canvas you are trying to create a div which contains a class and inline styles as a props/attributes and we are creating a canvas as a children of this div vnode. Hence, Instead of returning the vNode directly from setup(), it should return a render function that returns a 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`,
                    onm ousemove: e => renderer.mousemove(e),
                    onm ouseout: e => renderer.mouseout(e),
                    onm ouseup: e => renderer.mouseup(e),
                    onm ousedown: e => renderer.mousedown(e),
                    ref: 'canvas',
                    style: props.style,
                }, props.attrs))
            ].concat(props.hs || []))
       } ✅
    }
}

CodePudding user response:

First you are are not "calling" render function - you are just declaring it (Vue is caling it when rendering)

In Composition API you just need to return render function from 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)
  }
}
  • Related