-
Notifications
You must be signed in to change notification settings - Fork 0
/
create-app.js
69 lines (56 loc) · 1.87 KB
/
create-app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import { Vue, mixin } from "../src/index.js";
import { fixupRoot as setDataFixupRoot } from "../set-data/set-data.js";
/**
* Create and mount a Vue app
* @param {Object} spec
* @param {Element} [spec.element] The element to mount the app on. Defaults to `"#app"`
* @param {Element} [element] The element to mount the app on. Deprecated, use `spec.element` instead.
*/
export default function createApp(spec, element = spec.element) {
spec.mixins ??= [];
spec.mixins.push(mixin);
// Figure out root element
if (!element && element !== false && typeof document !== "undefined") {
// If there’s an element with id "app"…
let candidate = document.getElementById("app");
// That is not already a Vue app…
if (!candidate.__vue_app__) {
// …use that
element = candidate;
}
}
// Wrap data in a function as that's what Vue expects
if (typeof spec.data !== "function") {
let data = spec.data;
if (element) {
setDataFixupRoot(element, data);
}
spec.data = () => data;
}
// Any variables to expose?
if (spec.expose) {
for (let key in spec.expose) {
let value = spec.expose[key];
if (typeof value === "function") {
spec.methods ??= {};
// Global functions can produce errors if called with a different context
// and globalThis is a reasonable default context anyway
let isConstructor = !!value.prototype && value.prototype.constructor === value;
spec.methods[key] = isConstructor? value : value.bind(globalThis);
}
else {
spec.computed ??= {};
spec.computed[key] = () => value;
}
}
}
let app = Vue.createApp(spec);
if (!element) {
if (element !== false) {
console.warn("[MaVue.createApp] No element to mount app on. Call .mount() on the result of createApp() or pass in an element parameter. Set element: false to mute this warning.");
}
return app;
}
return app.mount(element);
}
export { Vue, mixin };