Я создал веб-компонент для общих c полей ввода, которые мне нужны для нескольких проектов. функциональность дизайна остается той же, только я должен использовать темы переключения в каждом проекте. поэтому я решил go с веб-компонентами. Один из проектов основан на Vue Js. В Vue js Содержимое DOM перерисовывается при каждом обновлении для обеспечения реактивности. Этот повторный рендеринг шаблона vue приводит к повторной инициализации моего пользовательского веб-компонента, что приведет к потере всех моих конфигураций, которые я назначил компоненту с помощью установщиков. Я знаю следующие решения. но я хотел использовать метод установки.
- передача данных в качестве атрибутов
- Передача конфигураций на основе событий.
- Использование Vue -направлений.
с использованием v-show вместо v-if
- три выше решения на самом деле не совпадают с тем, что я я пытаюсь создать.
Я создал пример проекта в jsfiddle для отображения моей проблемы. Каждый раз, когда я снимаю галочку и ставлю галочку, создаются новые экземпляры моего компонента. что вызывает потерю темы, которую я выбрал. (пожалуйста, проверьте количество активных ящиков) Для этого конкретного примера я хочу, чтобы синяя тема отображалась. но он продолжает меняться на красный
JSFiddle direct Link
class InputBox extends HTMLElement {
constructor() {
super();
window.activeBoxes ? window.activeBoxes++ : window.activeBoxes = 1;
var shadow = this.attachShadow({
mode: 'open'
});
var template = `
<style>
.blue#iElem {
background: #00f !important;
color: #fff !important;
}
.green#iElem {
background: #0f0 !important;
color: #f00 !important;
}
#iElem {
background: #f00;
padding: 13px;
border-radius: 10px;
color: yellow;
border: 0;
outline: 0;
box-shadow: 0px 0px 14px -3px #000;
}
</style>
<input id="iElem" autocomplete="off" autocorrect="off" spellcheck="false" type="text" />
`;
shadow.innerHTML = template;
this._theme = 'red';
this.changeTheme = function(){
this.shadowRoot.querySelector('#iElem').className = '';
this.shadowRoot.querySelector('#iElem').classList.add(this._theme);
}
}
connectedCallback() {
this.changeTheme();
}
set theme(val){
this._theme = val;
this.changeTheme();
}
}
window.customElements.define('search-bar', InputBox);
<!DOCTYPE html>
<html>
<head>
<title>Wrapper Component</title>
<script src="https://unpkg.com/vue"></script>
<style>
html,
body {
font: 13px/18px sans-serif;
}
select {
min-width: 300px;
}
search-bar {
top: 100px;
position: absolute;
left: 300px;
}
input {
min-width: 20px;
padding: 25px;
top: 100px;
position: absolute;
}
</style>
</head>
<body>
<div id="el"></div>
<!-- using string template here to work around HTML <option> placement restriction -->
<script type="text/x-template" id="demo-template">
<div>
<div class='parent' contentEditable='true' v-if='visible'>
<search-bar ref='iBox'></search-bar>
</div>
<input type='checkbox' v-model='visible'>
</div>
</script>
<script type="text/x-template" id="select2-template">
<select>
<slot></slot>
</select>
</script>
<script>
var vm = new Vue({
el: "#el",
template: "#demo-template",
data: {
visible: true,
},
mounted(){
let self = this
setTimeout(()=>{
self.$refs.iBox.theme = 'blue';
} , 0)
}
});
</script>
</body>
</html>