-
π‘ 21λ λ Vuejs 2λ²μ μ μ¬λ΄ κ°λ°νμ κ΅μ‘νκ³ μ μμ±νλ λ¬Έμμ λλ€. μ°Έκ³ ν΄μ£ΌμΈμ!
MDN Web docs λ₯Ό μΌλ§λ λ§μ΄ μ νμλμ ? μμ¦μ λͺ¨λ νλ‘ νΈμλ νλ μμν¬λ λΌμ΄λΈλ¦¬μμλ μ»΄ν¬λνΈ κΈ°λ° μν€ν μ³λ₯Ό ꡬννμ¬ λ³΅μ‘ν νλ©΄μ κΈ°λ₯μ κ°λ¨ν λΆλΆμΌλ‘ λλκ³ μ‘°λ¦½νλ κ³Όμ μ ν΅ν΄ νλ©΄μ ꡬννκ³ μμ΅λλ€. λνμ μΌλ‘ Vuejs, React λ±μ΄ μλλ°μ. μ΄λ° νλ μμν¬λ μλ‘μ΄ νμ€μ λ§λ€μ΄ λΈ κ²μ΄ μλ κΈ°μ‘΄μ κ²μ κ·Έλλ‘ λλκ³ μλ°μ€ν¬λ¦½νΈλ₯Ό ν΅ν΄ μ»΄ν¬λνΈλ₯Ό ꡬννμ΅λλ€. μ°λ¦¬κ° νλ‘ νΈμλ λΌμ΄λΈλ¬λ¦¬λ νλ μμν¬λ₯Ό λ§μ΄ μ νλ©΄μλ μΉ μ»΄ν¬λνΈλ±μ νμ€ κΈ°μ μ λν΄μλ μ λͺ¨λ₯΄λκ² κ°μ΅λλ€. μΉ μ»΄ν¬λνΈλ MDN WebDocs μμ κ·Έ μ€λͺ μ μ°Ύμ λ³Ό μ μλλ°μ.
μΉ μ»΄ν¬λνΈλ νλ©΄μ νμνκ³ κ·Έ νμλ νλ©΄μμ μ 곡νλ μ¬λ¬κ°μ§ κΈ°λ₯μ μ¬μ¬μ© κ°λ₯ν μ‘°κ°μΌλ‘ λλκ³ κ·Έκ²μ λ€μ 쑰립νμ¬ μ¬μ©ν μ μλλ‘ μ 곡νλ λ€μν κΈ°μ μ λͺ¨μμ΄λΌκ³ μ€λͺ λμ΄ μμ΅λλ€.
μ΄κ²μ΄ νμ€ κΈ°μ λ‘ κ°λ°λκΈ°κΉμ§ μ¬λ¬κ°μ§ μ΄μ λ€μ΄ μμ μ μκ² μ§λ§ λνμ μΌλ‘λ μ¬ μ¬μ©μ±κ³Ό κ·Έλ‘μΈν μμ°μ±μ λν λ¬Έμ λ₯Ό ν΄κ²°νκΈ° μν¨μ΄ μ»Έλκ² κ°μ΅λλ€. μ°λ¦¬κ° HTML κ³Ό CSSλ‘ νλ©΄μ νννκΈ°μν΄ λ°λ³΅ν΄μΌ νλ μμ λ€μ μκ°ν΄ λ΄ μλ€. λκ°μ κΈ°λ₯κ³Ό λμμΈμ κ°μ§κ³ μλ HTML μ CSSλ₯Ό νμν λ§νΌ λ°λ³΅ν΄μ μ½λ©μ ν΄μ£Όμ΄μΌ νμ΅λλ€. λν μΉνμ΄μ§λ₯Ό λμ μΌλ‘ νννκ±°λ μ¬μ©μμκ² μ¬λ¬κ°μ§ κΈ°λ₯μ μ 곡νκΈ° μν΄ μλ°μ€ν¬λ¦½νΈλ₯Ό μ¬μ©νμ΅λλ€. μλ°μ€ν¬λ¦½νΈλ₯Ό μ΄μ©νλ©΄ μ리먼νΈλ₯Ό ν¨κ³Όμ μΌλ‘ μ μ΄ν μ μμ§λ§ λ€λ₯Έκ³³μμ λμΌν κΈ°λ₯μ΄ νμν κ²½μ° κ³΅ν΅ κΈ°λ₯μΌλ‘ μ μΈμ ν΄μ£Όκ±°λ κ°μ μ½λλ₯Ό μ¬μ¬μ© νμ΄μΌ νμ΅λλ€. κ·Έλ¬λ―λ‘ ν νμ΄μ§μλ μλ‘ κ΄λ ¨μλ μλ°μ€ν¬λ¦½νΈ μ½λκ° λ€μ£½ λ°μ£½μ΄ λκΈ° λ§λ ¨μ΄κ³ μμ°μλλ₯Ό ν¬κ² λ릴λ§ν λ°©λ²μ΄ μ μλμ§ μμμ΅λλ€.
μΉ μ»΄ν¬λνΈλ μ΄λ¬ν λ¬Έμ λ€μ ν΄κ²°ν΄ μ€μ μμ΅λλ€. λͺκ°μ§ κΈ°λ₯λ€μ΄ μλλ° νλμ© μ΄ν΄λ³΄κ² μ΅λλ€.
컀μ€ν μ리먼νΈ
HTML νκ·Έλ HTMLμ½λλ₯Ό μ²λ¦¬ν΄μ£Όλ λΈλΌμ°μ κ° μ 곡νλ λͺκ°μ§ μλλ μμ½μ΄λΌκ³ λ³Ό μ μμ΅λλ€. HTML νκ·Έλ₯Ό ν΅ν΄ μ°λ¦¬λ νλ©΄μ ꡬμ±νμ΅λλ€. 컀μ€ν μ리먼νΈλ HTML νκ·Έλ₯Ό 컀μ€ν ν μ μλ κΈ°λ₯μ λλ€. λ΄κ° μνλ μ΄λ¦μ νκ·Έλ₯Ό λ§λ€κ³ μ¬μ©ν μ μμ΅λλ€. νκ·Έ μμλ μμ μμλ ν¬ν¨λ μ μμ΅λλ€.
customElements.define('word-count', WordCount, { extends: 'p' });
컀μ€ν μ리먼νΈλ μμκ°μ΄ κ°λ¨ν ννλ‘ κ΅¬νν μ μμ΅λλ€. μ΄λ°μμΌλ‘ μμ±λ μλ°μ€ν¬λ¦½νΈ μ½λκ° λμ νλ€λ©΄ μ΄λ¬ν HTML μ½λλ₯Ό ννν μ μμ΅λλ€.
<word-count />
define ν¨μμλ νκ·Έμ μ΄λ¦ λ§κ³ λ WordCount λΌλκ²κ³Ό { extends: 'p' } λΌλ νλΌλ―Έν°κ° μ λ¬λμλλ° λμΉκ° λΉ λ₯Έ λΆλ€μ μ΄λ―Έ λμΉ μ±μ ¨μμλ μκ² μ§λ§ WordCount λ μλ°μ€ν¬λ¦½νΈ ν΄λμ€, extends, Pλ p νκ·Έλ₯Ό μμνλ€λΌλ λ»μ λλ€. μμμ΄λΌλ λ¨μ΄κ° μμνμ€μλ μκ² μ§λ§ μ½κ² ννν΄μ λμΌν κΈ°λ₯μ νλλ‘ νκ² λ€ λΌκ³ μ΄ν΄νμλ©΄ λκ² μ΅λλ€. p νκ·Έλ λ μ΄μμμμ μΈλΌμΈμ μ±κ²©μ κ°μ§κ³ μμΌλ―λ‘ word-coun νκ·Έλ μΈλΌμΈμ μμ±μ κ°μ§κ² λ©λλ€.
ν΄λμ€λ₯Ό μ΄ν΄λ³ΌκΉμ ?
class WordCount extends HTMLElement { consturctor() { super(); } function open() { ... } }
ν΄λμ€μλ μ¬λ¬κ°μ§ ν¨μμ λ©μλκ° ν¬ν¨λ μ μμ΅λλ€. vuejs μ react μ²λΌ λΌμ΄ν μ¬μ΄ν΄ μ½λ°±λ μ‘΄μ¬ν©λλ€. ν΄λμ€μ ν¬ν¨λ λ©μλλ νκ·Έλ‘ νμ© λ λ μ΄λ κ² μ¬μ©ν μ μμ΅λλ€.
<script> var count = document.getElementById('word-count'); count.open(); </script>
word-count μ리먼νΈλ₯Ό λ³μμ μ λ νΈ ν λ€ ν΄λμ€μ²λΌ ν¨μλ₯Ό νΈμΆν μ μμ΅λλ€. open μ΄λΌλ ν¨μλ world-count μ λ΄λΆ κΈ°λ₯μ ν¬ν¨λμ΄ μμΌλ―λ‘, world-coint νκ·Έλ₯Ό ν΅ν΄ μ리먼νΈλ₯Ό λ³κ²½νκ±°λ μ΄λ²€νΈλ₯Ό μ£Όκ±°λ μ κ±°νκ³ νλ λ±μ κΈ°λ₯μ μμ±ν μ μκ³ μ΄λ¬ν κΈ°λ₯μ νλμ ν΄λμ€λ‘ μΊ‘μν ν μ μμ΅λλ€.
Shadow DOM
shadow dom μ μΉ μ»΄ν¬λνΈ μν€ν μ³μμ μΊ‘μνμ μ°μ₯μ μΌλ‘ λ³Ό μ μμ΅λλ€. 컀μ€ν μ리먼νΈλ κΈ°λ₯μ μΊ‘μνλ₯Ό ꡬνν μ μκ² ν΄μ€λ€λ©΄ shadow dom μ μ리먼νΈμ μ€μ½νμ κ°μ κ°λ μ μ μ©ν μ μμ΅λλ€. λΈλ‘ μ€μ½νλ λ³μμ μ κ·Ό λ μ΄μ΄κ° μμ΄μ ν΄λΉ λΈλ‘μ΄ μλλ©΄ μ κ·Όν μ μλ κ°λ μΈλ°μ. shadow domμΌλ‘ λ§λ€μ΄μ§ μλ¦¬λ¨ΌνΈ νΈλ¦¬λ μΈλΆμμ μ κ·Όν μ μλλ‘ μ νμ μ€μ μμ΅λλ€.
let shadow = elementRef.attachShadow({ mode: 'open' }); let shadow = elementRef.attachShadow({ mode: 'close' });
elementRefλ μ΄λ―Έ μ λ νΈ λ μλ¦¬λ¨ΌνΈ μΈμ€ν΄μ€μ λλ€. μ¬κΈ°μ attachShadow ν¨μλ₯Ό νΈμΆνλ©΄ μλ‘μ΄ shadow dom root κ° μμ±λ©λλ€. shadow dom root μλ μΌλ° λμ²λΌ λ€λ₯Έ μ리먼νΈλ₯Ό μΆκ°νκ±°λ μμ ν μλ μκ³ μ΄λ²€νΈ 리μ€λλ₯Ό μμ±ν΄ μ€μλ μμ΅λλ€.
shadow DOM μ΄ μΌλ° μ리먼νΈμ μ΄λ»κ² μμ©ν μ μλμ§ λ³΄μ¬μ£Όκ³ μμ΅λλ€. shadow dom μ μ€μ μΌλ° λ νΈλ¦¬μ λΆμ°©λκΈ° μ κΉμ§λ λ λλ§ λμ§ μμΌλ©° λΆμ°©μ΄ λ¨κ³Ό λμμ λ λλ§μ΄ λκΈ° λλ¬Έμ. μ¬λ¬κ°μ§ μμ μμλ₯Ό ν¬ν¨ν μ»΄ν¬λνΈλ₯Ό μ μνμ¬ μ¬μ¬μ© ν μ μμ΅λλ€.
μ΄μ shadow dom μ μ¬μ©νλ λ°©λ²μ μ΄ν΄λ³΄κ² μ΅λλ€.
class SimpleModal extends HTMLElment { construct() { super(); // shadowDOM μμ± this.attachShadow({ mode: 'open' }); // λͺ¨λ¬μ νμ μ¬λΆ this._visible = false; // λͺ¨λ¬μ μ리먼νΈμ μ€νμΌ νν this.shadowRoot.innerHTML = ` <div class="modal_wrap"> ... </div> `; } // κ°μ νΈλ¦¬κ° document μ μ°κ²°λ ν μ€ν connectedCallback() { this._modal = this.shadowRoot.querySelector('.modal-wrap'); this.shadowRoot.querySelect('.close').addEventListener('click', this._hide.bind(this)); this.shadowRoot.querySelector('.modal-box').style.backgroundColor = this.getAttribute('bgcolor'); } // λͺ¨λ¬μ λ«μ _hide() { this._visible = true; this._modal.style.display = 'none'; } // λͺ¨λ¬μ μΌ show() { this._visible = false; this._modal.style.display - 'block'; } } // 컀μ€ν μλ¦¬λ¨ΌνΈ λ±λ‘ customElements.define('simple-modal', SimpleModal);
SimpleModal μ 컀μ€ν μ리먼νΈλ₯Ό ν΅ν΄ shadow dom μ μμ±νκ³ λ΄λΆ ν¨μλ₯Ό μ΄μ©ν΄ shadow element λ₯Ό 컨νΈλ‘€ ν΄μ£Όμμ΅λλ€. μλ¦¬λ¨ΌνΈ ν΄λμ€κ° μΈμ€ν΄μ€ν λ λ (λμμ λ λλ§ λ λ) shadow dom μ μμ±νμ¬ μΌλ° μ리먼νΈμ μ μ°© λ μ μλ μνκ° λ©λλ€.
νλ‘ νΈμλ λΌμ΄λΈλ¬λ¦¬λ νλ μμν¬λ₯Ό μ¬μ©νμ§ μκ³ μλ°μ€ν¬λ¦½νΈμ HTML νκ·Έλ§ κ°μ§κ³ μ»΄ν¬λνΈλ₯Ό ꡬνν μ μλ€λ μ μ΄ μ μ νμ΅λλ€. μ΄λ¬ν νμ€ κΈ°μ μ΄ κ³μν΄μ λ°μ λκ³ μμ§λ§ μμ§κΉμ§λ reactμ vuejs μ κΈ°λ₯μ λ°λΌκ°κΈ°μλ λΆμ‘±ν λΆλΆμ΄ λ§μ΄ 보μ λλ€. νμ€ κΈ°μ μλ μ΄ μΈμλ template κ³Ό slot λ±μ μΉ μ»΄ν¬λνΈλ₯Ό μν κΈ°μ λ€μ΄ μμΌλ―λ‘ λ€μ ν¬μ€ν μμ λ€λ€λ³΄λλ‘ νκ² μ΅λλ€.
μ 체 μ½λλ μ¬κΈ°μμ νμΈν μ μμ΅λλ€.
'Tech > Frontend' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
MDN Webdocμ νμ€, Template & Slot (0) 2023.05.23 Vue2λ₯Ό AWS S3μ λ°°ν¬νκ³ μ΄μν΄λ³΄μ (0) 2023.05.04 λκΈ