Subscribe on changes!

`createElement` in `RendererOptions` require container arguments

avatar
Oct 12th 2021

What problem does this feature solve?

The custom renderer need to do a things depending on the container.

What does the proposed API look like?

createElement: (tag, isSVG, is, props, container): CustomElement => {
    if (container...) {
    // do some thing...
    }
    const el = createElement(tag, container)
    return el
}

createText: (text, container) => {
    return createTextNode(text, container)
}

createComment: (text, container) => {
    return createComment(text, container)
}
avatar
Oct 12th 2021

The custom renderer need to do a things depending on the container.

That doesn't really qualify as a use case / problem description. Can you provide more details? When do you need this? What for? Why?

avatar
Oct 12th 2021

The custom renderer need to do a things depending on the container.

That doesn't really qualify as a use case / problem description. Can you provide more details? When do you need this? What for? Why?


const customNodeOps: Omit<RendererOptions<CustomNode, CustomElement>, 'patchProp'> = {
  createElement: (tag, isSVG, is, props, container): CustomElement => {
    if (container...) {
      // do some thing...
    }
    const el = createCustomElement(tag, container, is ? { is } : undefined)
    // container... do some thing
    return el
  },

  createText: (text, container) => {
    // this func inner need container
    return createCustomTextNode(text, container)
  },

  createComment: (text, container) => {
    // this func inner need container
    return createCustomComment(text, container)
  },
  ...... others
}

const rendererOptions = extend({ patchProp }, customNodeOps)
const renderer = createRenderer(rendererOptions)
const app = renderer.createApp(App)
avatar
Oct 12th 2021

That doesn't really show any use cases for that code.

avatar
Oct 13th 2021

That doesn't really show any use cases for that code.

// run in JSCore context or WebWorker
export function createCustomElement(tagName: string, container: CustomElement, options?: ElementCreationOptions): CustomElement {
    const page = container.page
    const el = new CustomElement(tagName)
    el.page = page
    el.nodeID = page.incID()
    page.elements.set(el.nodeID, el)
    // send dom message to WebView
    page.virtualDomSync(el)
    return el
}
avatar
Oct 13th 2021

This is a very specific design constraint for your custom renderer - i.e. your element creation requires access to the current custom "page" object - but it doesn't logically leads to "createElement should pass the parent container".

Where is your page created? Why can't it be made available to your renderer methods in other ways? Why does it require Vue to change its API in order to fit this use case?

avatar
Oct 13th 2021

@yyx990803

There may be multiple pages rendered at the same time, and the current page cannot be determined in createElement.

export function renderPage(route: string) {
    const page = new Page(pid += 1, route)
    pages.set(page.pid, page)

    const pageComponent = pageComponents.get(page.router)
    const vnode = createVNode(pageComponent)
    // the page is root component
    renderer.render(vnode, page)
}

subscribe("webview_ready", (message) => {
    // sync dom to webview
    renderPage(message.route)
})
avatar
Oct 21st 2021

one usage can be for plugin (inside app.use(...) ) to generate the element outside #app perhaps it should be app.inflate(...) instead of createElement or createTextNode to utilize the vue template

https://github.com/vuejs/vue-next/issues/4774