Created
February 24, 2018 04:15
-
-
Save isometriq/8843fa3011fd40c3ef0e83870de0430c to your computer and use it in GitHub Desktop.
Extending a Vue component template
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
function isObject(value) { | |
return value !== null && value !== undefined && typeof value === 'object'; | |
} | |
function isArray(value) { | |
return value && value.constructor === Array; | |
} | |
function isString(value) { | |
return typeof value === 'string'; | |
} | |
// Replace the slot default content of a component | |
function extendTemplate(template, slots) | |
{ | |
Object.keys(slots).map((slotName, index) => | |
{ | |
let regexPattern = slotName=='default' ? '<slot[\s\S]*>' : '<slot(.+name="('+slotName+')")?[\s\S]*>' | |
let regex = new RegExp(regexPattern, 'ig'); | |
let results = []; | |
let result = null; | |
while ((result = regex.exec(template)) !== null) { | |
results.push(result); | |
} | |
if (!results.length) { | |
return false; | |
} | |
results.map((result, index) => { | |
if (slotName=='default' || (result[2]!=null && result[2]==slotName)) | |
{ | |
let start = result.index + result[0].length; | |
let end = result.input.indexOf('</slot>', start); | |
if (end == -1) { | |
return; | |
} | |
template = template.substring(0, start) + slots[slotName] + template.substring(end); | |
} | |
}); | |
}); | |
return template; | |
} | |
// Detect if extending and try to apply template extension | |
function extendComponent(component) | |
{ | |
if (isObject(component.extends) && isString(component.extends.template) && (isObject(component.template) || isString(component.template))) | |
{ | |
if (isString(component.template)) { | |
component.template = { default: component.template }; | |
} | |
component.template = extendTemplate(component.extends.template, component.template); | |
// Merge components as they can be needed in the extended template | |
if (isObject(component.components) && isObject(component.extends.components)) { | |
component.components = Object.assign(component.components, component.extends.components); | |
} | |
component.computed = Object.assign({}, component.computed ? component.computed : {}, { | |
super() { | |
return this.constructor.options.extends; | |
} | |
}); | |
} | |
return component; | |
} | |
// Component do-it-all decorator | |
function component(component) { | |
return extendComponent(component); | |
} | |
export default component | |
export { component, extendComponent, extendTemplate } |
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
import component from './component' | |
export default component({ | |
name: 'form', | |
template: ` | |
<div> | |
<div> | |
<slot name="header"><h2>{{ title }}</h2></slot> | |
</div> | |
<div> | |
<slot name="fields"></slot> | |
</div> | |
<div> | |
<!-- save cancel buttons, etc... --> | |
</div> | |
</div> | |
`, | |
props: { | |
title: String | |
}, | |
data: ()=>({ | |
form: { | |
data: {} | |
} | |
}), | |
methods: { | |
reset() { | |
// clear form data etc.. | |
} | |
submit() { | |
// send form data etc.. | |
} | |
} | |
}) |
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
import Form from './Form' | |
export default component({ | |
name: 'user-form', | |
extends: Form, | |
template: { | |
`fields`: ` | |
<p>Name: <input type="text" v-model="form.data.name" /></p> | |
<p>Email: <input type="text" v-model="form.data.email" /></p> | |
` | |
}, | |
props: { | |
title: {default: 'User Form'} | |
}, | |
methods: { | |
userSpecific() { | |
// user specific logic etc.. | |
} | |
} | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment