forked from regiomedia/bitrix-project
-
Notifications
You must be signed in to change notification settings - Fork 0
/
vueInvoker.js
73 lines (59 loc) · 2.18 KB
/
vueInvoker.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
70
71
72
73
/**
* Модуль для автоматической инициализации Vue компонентов на странице сайта
*
* Метод `init(Vue, components)` Загружает компоненты в соответствующие элементы на странице
* и передает в них изначальные данные
*
* Например, вместо блока:
*
* <div class="vue-component" data-component="DemoApp" data-initial='{"test": "data"}'></div>
*
* Будет подключен компонент DemoApp (если тот присутствует в объекте-коллекции `components`)
*
* и в его свойство initial будет передан JSON-объект {"test": "data"}
*
* Передача в метод экземпляра `Vue` позволяет предварительно его сконфигурировать:
* например, добавить Vuex-store и/или разнообразные плагины и миксины.
*/
import logger from './logger';
export default {
init(Vue, components, options) {
this.options = Object.assign(this.options, options);
const nodes = Array.from(document.querySelectorAll(this.options.selector));
const collection = [];
nodes.forEach((item) => {
let initialData = item.dataset[this.options.initialDataAttr];
if (initialData !== undefined) {
try {
initialData = JSON.parse(initialData);
} catch (e) {
logger.warn(e);
}
}
if (components[item.dataset[this.options.componentDataAttr]] !== undefined) {
collection.push(this.createComponentInstance(
Vue,
item,
components[item.dataset[this.options.componentDataAttr]],
initialData,
));
}
});
return collection;
},
options: {
selector: '.vue-component',
componentDataAttr: 'component',
initialDataAttr: 'initial',
},
createComponentInstance(Vue, element, component, data) {
return new Vue({
el: element,
render(h) {
return h(component, {
props: { initial: data },
});
},
});
},
};