Johannes Kissel & Michael Müller
Software Developer
at
in Karlsruhe
Enthusiastic about …
Full Stack Developer
at
in Karlsruhe
Enthusiastic about …
… and it's legacy, but …
… not that kind of legacy …
… or that kind:
It's vivid and
constantly improved and extended
Frankfurt main station, © Urmelbeauftragter / CC-BY-SA-3.0 (via Wikimedia Commons)
Refactoring on the go demands
maximum interoperability
const ELEMENT_NAME = 'd-toggle-button';
class ToggleButton extends HTMLElement {
connectedCallback () {
this.classList.add(ELEMENT_NAME);
this.setAttribute('role', 'button');
this.addEventListener('click', () => {
this.pressed = !this.pressed;
this.dispatchEvent(new CustomEvent('toggle', {bubbles: true}));
});
}
set pressed (value) {
this.setAttribute('aria-pressed', value);
}
get pressed () {
return this.getAttribute('aria-pressed') === 'true';
}
}
customElements.define(ELEMENT_NAME, ToggleButton);
const button = document.createElement('d-toggle-button');
button.textContent = 'Button';
button.pressed = true;
button.addEventListener('toggle', () => {
console.log(button.pressed);
});
document.body.append(button);
import ToggleButton from 'ui/toggle-button';
// or
const ToggleButton = customElements.get('d-toggle-button');
// Constructor
const button = new ToggleButton();
…
const $button = $('<d-toggle-button>')
.text('Button')
.prop('pressed', true)
.on('toggle', () => console.log($button.prop('pressed')))
.appendTo(document.body);
new Vue({
el: '#app',
template: `<d-toggle-button
:pressed.prop="pressed"
@toggle="onToggle">Button</d-toggle-button>`,
data: { pressed: true },
methods: {
onToggle: event => console.log(event.target.pressed)
}
});
Railroad ties, © Störfix / CC-BY-SA-3.0 (via Wikimedia Commons)
A software component is a
unit of composition with contractually specified interfaces and explicit context dependencies only.
UI components have a name and can be reused.
class MyComponent extends HTMLElement {
…
}
customElements.define('d-my-component', MyComponent);
(Google primer on custom elements)
class MyButton extends HTMLButtonElement {
…
}
customElements.define('d-my-button', MyComponent, {extends: 'button'});
// Usage:
document.createElement('button', {is: 'd-my-button'});
// or
// new MyButton();
// <button is="d-my-button">My Button</button>
<script>
if (window.customElements) {
// Make the browser work with transpiled custom elements.
document.write('<script src="native-shim.js"></script>');
} else {
// Polyfill custom elements.
document.write('<script src="custom-elements.min.js"></script>');
}
</script>
⇒ We look forward to extend built-in elements in the future.
class MyComponent extends HTMLElement {
constructor () {
// Called when the element is created or upgraded.
super(); // Don't forget to call super().
…
}
connectedCallback () {
// Called when the element is connected to the DOM.
}
disconnectedCallback () {
// Complement to the connectedCallback()
}
}
class MyComponent extends HTMLElement {
static get observedAttributes() {
return ['some-attribute']; // Return attribute names to observe.
}
attributeChangedCallback (name, oldValue, newValue) {
// Called when the observed attributes' values change.
}
}
class ToggleButton extends HTMLElement {
connectedCallback () {
this.addEventListener('click', () => {
this.pressed = !this.pressed;
this.dispatchEvent(new CustomEvent('toggle', {bubbles: true}));
});
}
set pressed (value) {
this.setAttribute('aria-pressed', value);
}
get pressed () {
return this.getAttribute('aria-pressed') === 'true';
}
}
class Tabs extends HTMLElement {
constructor() {
super();
const shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.innerHTML = `
<style>#tabs { border-bottom: 1px solid; }</style>
<div id="tabs">
<slot name="tabs" />
</div>
<div id="panels">
<slot />
</div>
`;
}
}
⇒ We do not use the Shadow DOM and do not recommend it.
<ul id="todoList"></ul>
<template id="todoTemplate">
<li>
<label>
<input type="checkbox"> <span class="text"></span>
</label>
</li>
</template>
const todos = document.querySelector('#todoList');
const template = document.querySelector('#todoTemplate');
template.content.querySelector('.text').textContent = 'Give a talk';
template.content.querySelector('input').checked = true;
todos.append(document.importNode(template.content, true));
⇒ HTML Templates work nicely, but we don't use them, yet.
Keep calm and #UseThePlatform
Departing train, © Xenotron / CC BY 4.0 (via Wikimedia Commons)
npm install -g @vue/cli
{{ greeting }} World!
import Vue from "vue";
import HelloWorld from "./HelloWorld.vue";
Vue.component("hello-world", HelloWorld);
new Vue({
el: "#app",
template: " "
});
Keep calm and #becomeaddicted
© Ryoji Iwata via unsplash.com