-
-
Notifications
You must be signed in to change notification settings - Fork 33.7k
Description
Hi,
Fairly often (1, 2, 3) when building reusable components I use the same pattern of nested components.
The pattern consists of a parent component using the slot-directive and a child component which must be nested to work correctly. The child component also has a slot-directive to contain the custom content.
The aim of the pattern is to have a defined parent-child behavior with the support for custom content.
(Would be useful for all sorts of popular ui-components, like wizard, accordion, etc.)
Example from vue-position-after-transform:
<vc-pat> //parent component
<vc-patc> //child component
Text 1 //custom content
</vc-patc>
<vc-patc> // parent:child - 1:n
Text 2
</vc-patc>
</vc-pat>
There are several problems with this approach in vue. Most important, components build with this pattern can't be nested and data passing to the child is verbose (using $children
in the parent and filtering only the "real" child components).
example from vue-position-after-transform:
for child in @$children
# reason why I can't nest the components,
# $children will contain ALL somewhere nested patc-components
# not only the direct children
if child.isPatc
process(child)
I was thinking about it for a while and I found a good solution:
An additional directive 'plugin' on the slot
component with the following features:
- slot only accepts components (should throw If has plain content)
v-bind
to pass data to components- deeper nested components are put in childs
$children
instead of parents - child should be evaluated in the parent's parent scope, like normal slot
- the directive optionally takes a string which must match the
name
of the child component (should throw if a direct child has no or the wrong name) or an expression which is evaluated in the childrens scope and must be true.
The last point would allow different children with different behavior on the same parent,
for example when building an accordion, there could be a child component which collapses when another one is opened and one which remains opened.
In the template of the parent component slot
with plugin
would be used and in the child slot
without plugin
The downside: I looked into the slot component and found no easy way of achieving this.
What do you think?