-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
506781c
commit 71760f4
Showing
2 changed files
with
76 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
# What is vue-vnode-utils? | ||
|
||
`vue-vnode-utils` is a collection of functions that can be used to manipulate Vue VNodes. They are intended to be used inside `render` functions. The most common use case would be manipulating an array of child VNodes returned by a slot: | ||
|
||
```vue | ||
<script> | ||
export default { | ||
render() { | ||
const children = this.$slots.default() | ||
// How can we change the VNodes in `children` here? | ||
// ... | ||
} | ||
} | ||
</script> | ||
``` | ||
|
||
Working with the array of children is sometimes relatively straightforward, but it can become complicated if the slotted content is using directives such as `v-for` or `v-if`. In particular, a `v-for` will introduce a fragment VNode, which wraps around the VNodes that represent the components and elements generated by the `v-for`. | ||
|
||
In general, manipulating VNodes is quite difficult, but `vue-vnode-utils` can help with some of the most common cases. The various helpers can be used to iterate over the 'top-level' child VNodes, including those wrapped in fragments. They can then be used to add or remove VNodes, or change the props of the existing VNodes. | ||
|
||
An example of adding a CSS `class` to the children in a slot: | ||
|
||
```js | ||
import { h } from 'vue' | ||
import { addProps } from '@skirtle/vue-vnode-utils' | ||
|
||
export default { | ||
render() { | ||
const children = addProps(this.$slots.default(), () => { | ||
return { | ||
class: 'my-child' | ||
} | ||
}) | ||
|
||
return h('div', children) | ||
} | ||
} | ||
``` | ||
|
||
An example of inserting an `<hr>` between each of the children: | ||
|
||
```js | ||
import { h } from 'vue' | ||
import { betweenChildren } from '@skirtle/vue-vnode-utils' | ||
|
||
export default { | ||
render() { | ||
const children = betweenChildren(this.$slots.default(), () => h('hr')) | ||
|
||
return h('div', children) | ||
} | ||
} | ||
``` | ||
|
||
There are more detailed examples, with demos, later in the guide. The key thing to appreciate is that these components will work even if the slotted content is using directives like `v-for` or `v-if`. The helper functions will walk the tree of fragments created by `v-for` and skip over the hidden comment nodes created by `v-if`, yielding the component and element nodes that would typically be regarded as the 'direct' children. | ||
|
||
Is manipulating VNodes like this actually a good idea? Probably not. Most of the time it'd be better to solve the problem some other way. But if you find yourself in one of those rare edge cases where you really do need to tweak VNodes then it's probably better to use a library to smooth over some of the problems for you. | ||
|
||
`vue-vnode-utils` doesn't replicate functionality that is already present in Vue itself. In particular, you should be familiar with [`isVNode()`](https://vuejs.org/api/render-function.html#isvnode) and [`cloneVNode()`](https://vuejs.org/api/render-function.html#clonevnode). That said, the helpers in `vue-vnode-utils` are designed in such a way that those core functions are often unnecessary. |