UNPKG

@muban/muban

Version:

Writing components for server-rendered HTML

102 lines (101 loc) 3.86 kB
import { devtoolsInitApp, devtoolsUnmountApp } from '../utils/devtools'; import { registerGlobalComponent } from '../utils/global'; import { mount } from '../utils/mount'; const version = '10'; export function createAppContext() { return { app: null, config: { // isNativeTag: NO, // performance: false, // globalProperties: {}, // optionMergeStrategies: {}, // isCustomElement: NO, // errorHandler: undefined, // warnHandler: undefined, }, components: {}, provides: Object.create(null), }; } let uid = 0; export function createApp(rootComponent) { // if (rootProps != null && !isObject(rootProps)) { // console.warn(`root props passed to app.mount() must be an object.`); // rootProps = null; // } const context = createAppContext(); let isMounted = false; // eslint-disable-next-line no-multi-assign const app = (context.app = { _uid: uid++, _component: rootComponent, _instance: null, _props: null, _container: null, _context: context, version, get config() { return context.config; }, set config(v) { // eslint-disable-next-line no-console console.warn(`app.config cannot be replaced. Modify individual options instead.`); }, component(...components) { registerGlobalComponent(...components); return app; }, mount(rootContainer, template, data) { var _a, _b; if (!isMounted) { const component = mount(app, rootComponent, rootContainer, template, data); app._instance = component === null || component === void 0 ? void 0 : component.__instance; if (app._instance) { app._instance.appContext = context; } isMounted = true; app._container = (_b = (_a = app._instance) === null || _a === void 0 ? void 0 : _a.element) !== null && _b !== void 0 ? _b : null; // for devtools and telemetry // (rootContainer as any).__vue_app__ = app; // TODO: devtools // if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) { devtoolsInitApp(app, version); // } return component; } // eslint-disable-next-line no-console console.warn(`App has already been mounted.\n` + `If you want to remount the same app, move your app creation logic ` + `into a factory function and create fresh app instances for each ` + `mount - e.g. \`const createMyApp = () => createApp(App)\``); }, unmount() { if (isMounted) { // TODO unmount original container // render(null, app._container); // TODO: devtools // if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) { devtoolsUnmountApp(app); // } } else { // eslint-disable-next-line no-console console.warn(`Cannot unmount an app that is not mounted.`); } }, provide(key, value) { if (key in context.provides) { // eslint-disable-next-line no-console console.warn(`App already provides property with key "${String(key)}". ` + `It will be overwritten with the new value.`); } // TypeScript doesn't allow symbols as index type // https://github.com/Microsoft/TypeScript/issues/24587 context.provides[key] = value; return app; }, }); context.app = app; return app; }