instapack
Version:
All-in-one TypeScript and Sass compiler for web applications!
55 lines (46 loc) • 1.56 kB
text/typescript
import * as Vue from 'vue';
type VueAsync = () => Promise<typeof import('*.vue')>;
type ConfigureVueApp = (app: Vue.App<Element>) => void;
/**
* Convert a hyphenated string to camelCase.
*/
function hyphenToCamelCase(name: string) {
return name.replace(/-(.)/g, (_match: string, char: string) => {
return char.toUpperCase();
});
}
/**
* Attempts to extract element attributes as string map.
* @param el
* @returns
*/
function convertElementAttributesToPropsMap(el: Element): Record<string, string> {
if (el.hasAttributes() === false) {
return {};
}
const result: Record<string, string> = {};
for (const attribute of el.attributes) {
const name = hyphenToCamelCase(attribute.name);
result[name] = attribute.value;
}
return result;
}
/**
* For each matching HTML Elements, render and mount a Vue Component asynchronously.
* Passes Element attributes as string to props. Kebab-case attributes will be converted to camel-case.
* @param tag
* @param factory
* @param configure
*/
export function renderAsyncComponent(tag: string, factory: VueAsync, configure?: ConfigureVueApp): void {
const ac = Vue.defineAsyncComponent(factory);
const elements = document.getElementsByTagName(tag);
for (const el of elements) {
const props = convertElementAttributesToPropsMap(el)
const app = Vue.createApp(ac, props);
if (configure) {
configure(app);
}
app.mount(el);
}
}