Батор Кореев
Drupal&frontend-разработчик
Модуль создадим любым известным/удобным для вас способом, а кто имеет опыт работы с CLI то воспользуемся командой drupal gm
назовем наш модуль my_vue_component
Создаем форму настроек, надеюсь у вас не будет никаких затруднений, тут ничего сложного. CLI drupal gfc
Создаем файл библиотек нашего модуля с названием my_vue_component.libraries.yml
#our files
main:
js:
assets/js/my_vue_component.js: {}
#include lib vue.js from vuejs module
dependencies:
- vuejs/vue
- core/drupal
- core/drupalSettings
Имплементируем хук для подключения наших файлов/библиотек и выведем/отправим наши данные из поля "Elements"
/**
* Implements hook_page_attachments_alter().
*/
function my_vue_component_page_attachments_alter(array &$attachments) {
$elems = \Drupal::config('my_vue_component.settings')->get('elems');
$elems = array_filter(explode("\r\n", $elems));
$attachments['#attached']['drupalSettings']['myVueComponent']['elems'] = $elems;
$attachments['#attached']['library'][] = 'my_vue_component/main';
}
В заключении нам остается только создать файл assets/js/my_vue_component.js и подключить vue и необходимый компонент
(function (Drupal, drupalSettings) {
Drupal.behaviors.MyVueComponent = {
attach(context) {
let elems = drupalSettings.myVueComponent.elems;
if (elems.length) {
this.buildMyVueCmpnt.includeVSelect('https://unpkg.com/vue-select@latest', () => {
Vue.component('v-select', VueSelect.VueSelect);
elems.forEach(elem => {
let ce = document.querySelectorAll(elem);
this.buildMyVueCmpnt.build(ce);
})
});
}
},
buildMyVueCmpnt: {
build: function (elem) {
if (elem.length) {
elem.forEach(ce => {
ce.setAttribute('v-model', 'selected');
let ceo = this.getOptions(ce.options);
this.createComponent(ce, ceo);
})
}
},
createComponent: (element, values) => {
let selement = element.options[element.selectedIndex].removeAttribute('selected');
let parent = element.parentElement;
element.style.display = 'none';
let VueCmpnt = document.createElement('v-select');
VueCmpnt.setAttribute('v-model', 'tmpSelected');
VueCmpnt.setAttribute(':options', 'options');
VueCmpnt.setAttribute('label', 'text');
parent.appendChild(VueCmpnt);
new Vue({
el: '.' + parent.className.split(' ').join('.'),
data: {
selected: values[0].value,
tmpSelected: values[0].value,
options: values
},
watch: {
tmpSelected: function (value) {
this.selected = value ? value.value : ''
}
}
});
},
getOptions: options => {
let output = [];
for (i = 0; i < options.length; i++) {
output.push({
value: options[i].value,
text: options[i].text
});
}
return output;
},
includeVSelect: (url, callback) => {
let script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
script.onreadystatechange = callback;
script.onload = callback;
document.getElementsByTagName('head')[0].appendChild(script);
}
}
};
}(Drupal, drupalSettings));