lundi 23 janvier 2023

Control child's layout from parent in Vue

is there an idiom in Vue ( let's say Vue2) to control child's layout?

The child is supposed to provide a logically coupled 'template elements' (e.g. el-1, el-2) and I/parent consumer want to pick how to arrange layout. I may want them to be displayed in column or maybe the second one should be a tooltip for the first one on another occasion.

I know that I can use scoped slots to access child's information but el-1 and el2 are complex enough that I would prefer not to recreate them but do something along those lines:

// NOT a valid VUE syntax

// parent 
<template>
  [...]
  <TheChild>
    <div>
      <el-1-provided-by-the-child-somehow/>
      <q-tooltip> 
        <el-2-provided-by-the-child-somehow/>
      </q-tooltip>
    </div>
  </TheChild>
  [...]
</template>

// child
<template>
  <slot>
      // I know this is a place for a default content but just for illustration,
      // let's say this is a way to 'emit' two templates to the parent:
      <....> // here is a non trivial template for el-1
      <....> // here is a non trivial template for el-2
  </slot>
</template>

I failed to find a solution, maybe because of my inability to phrase the question precisely. What I currently do always contains code duplication to some extent and is not acceptable in general.

I saw e.g. https://stackoverflow.com/a/42701426/4251542 but I need to be a whole piece of template defined in a child. So having access to child's state is not enough.

Now that I wrote this I came with an ugly idea, TheChild logic can be packaged as a mixin that additionally provides everything needed by el-*s. Then el-1 and el-2 are defined as separate components but heavily depend on inject. With provide/inject the parent wouldn't have to care about passing relevant props to el-*s. But that's ugly because it is obscure, el-* should rather take props and be nice presentational components, mixin names can collide with the consumer logic.

Did I miss something basic, the really feels like something that should be easy to do. But maybe I approach it from a wrong angle.

Aucun commentaire:

Enregistrer un commentaire