The loader allows you to extend templates for SFC by overriding slots.
Install the loader by running:
npm npm i --save vue-template-extends
Add loader to Webpack config in module.rules
:
// webpack.config.js
module.exports = {
module: {
rules: [
{
resourceQuery: /blockType=template-extends/,
loaders: ['vue-template-extends']
}
]
}
}
For example, your base component has template:
<!-- BaseComponent.vue -->
<template>
<div>
<slot>BaseComponent</slot>
<slot name="header">Base header</slot>
Some common content
</div>
</template>
To override slots from base component, you must create in child component file custom block <template-extends>
with attribute base
that contains a relative path to base component template (without file extension). This block should contain <slot>
tags with optional name
attribute. Default name for slots is default
(like in VueJs).
<!-- ChildComponent.vue -->
<template-extends base="./BaseComponent">
<slot>ChildComponent</slot>
<slot name="header">Child header</slot>
</template-extends>
When loader used for <template-extends>
custom block, it gets evaluated (recursively by base
-attribute) template string from parent component defined in base
attribute. Then it replaces <slot>
-tags content in parent template string with related (matched by name
-attributes) <slot>
-tags content in <template-extends>
-block. All this happens on the server during build.
Then on the client-side in user's browser, evaluated template compiled by Vue.compile()
to renders functions (render
and staticRenderFns
), that is sets as component options.
In one of my projects I have some complex forms with small differences in some places. Unfortunately VueJs by default don't allow extends a template's blocks (like @yeld/@extends/@section in Laravel Blade).
Possible solutions that I know is:
- Use template pre-processor for custom template engine, that supports extends templates:
- Use custom loaders:
- Vue Slot Loader - It has tricky implementation (generated slots) and therefore issues for many use cases. I have tried to improve this implementation, but still has many issues in real world usage.
- vue-inheritance-loader - The main disadvantage is that this module replaces default
vue-loader
. Also, I have an issue to use it with Laravel Mix.
In fact this loader inspired by Vue Slot Loader and grown from the last (thanks to @SasanFarrokh).