Subscribe on changes!

Dynamic template rendering and parent-children structure

avatar
Dec 31st 2022

What problem does this feature solve?

In last three weeks, my purpose is to modify Vue template before rendering. after I read some mysterios source code, reviewed all related issues in Github, tried out every method I can imagine, finally I have some new findings to share with the community.

As I believe, template should be dynamic, if we can change it before rendering, that'll be great! For example, clients may have customized views, users may have various permissions, the backend system may simply return a new data mapping. In all cases, we don't want to change the frontend.

That's what we do in Vue2:

  1. in template: set the place-holder html tag
  2. before/created: get this.$options.el, replace tag with actual HTML code
  3. before/mounted: Vue render the template

In Vue3, there's a similar solution:

  1. template: set a fake child with string template
  2. setup: pass reactive data/function, pass template text to children, JSX or h() should also work.
  3. render: Vue render the template (children are hacked by customized HTML code)

dynamic rendering

Question 1: why it's so hard to get there! Vue3 can simply provide a hook for template change before rendering.

JS+DOM is a simple way to write HTML code in vue style. If not rendered, why do we assume it's slow? Framework such as Vue doesn't need to take care the dirty things until templates reach the final step (rendering). We only need two checkpoints: One is the original template at the beginning, the other is the final version before mount. JSX dooms to bring HTML codes everywhere, why the framework needs to do performance tuning for all those dirty code? To me, Vue compiler is great, JSX is the gun I don't want to use.

Another question is about v-model. It's really hard to write correctly in JSX or h(). Do we still need that in Vue3? regarding issue #6151, here's another answer.

In Java, by default, objects pass directly from one subroutine to another. Only when we need a copy, then we do a data clone. What's the risk if parent directly pass reactive data to children?

Even though I understand props/emits/slots, I still feel painful to build a business comp. In most cases, parent owns the data, children process the data for some special purposes. Functional components is the right direction, it'll be better if we can forget the data definition, cuz Typescript actually adds more burden.

Question 2: Can we simplify the data exchange between parents and children?

Below is a typical page view. Overall layout is fixed, inside routeview, there're dynamic comps such as div portions, popup windows, not like non-business comps, they share the same parent data. Usually we open a list, add/update/delete some data, after it's done, we close the page, move on to the next one. That's straight forward, no deep loop for parent-children. 9

Are there anyone like me to believe that we should have a flat structure, rather than the deep tree of parent/children?

Any opinion?

What does the proposed API look like?

a hook to change template before rendering direct data exchange between parent and children (a simple way without props/store/inject)