Creating a JavaScript Framework "KWMJS" πŸš€

<aside> ℹ️ This mini framework aims to explain by example the basics of:

KWMJS Overview.png

<aside> ℹ️ Everytime we start the practical lesson the first thing you need to do is to create a new folder and clone the project repository into it with the console command e.g. git clone <https://github.com/jk-oster/kwm-example.git>.

After each practical lesson you have a week πŸ—“οΈ to complete the steps for the lesson and hand them in via Moodle.

</aside>

Exercises

Lesson 1

<aside> πŸ’‘ Copy the repository to your PC with git clone <https://github.com/jk-oster/lesson-1.git>. Navigate into the project folder lesson-1 and start the development server with npx vite β†’ click the link of the command output to open the development page.

</aside>

Lesson 2

<aside> πŸ’‘ Copy the repository to your PC with git clone <https://github.com/jk-oster/lesson-2.git>. Navigate into the project folder lesson-2 and start the development server with npx vite β†’ click the link of the command output to open the development page.

</aside>

Lesson 3

<aside> πŸ’‘ Copy the repository to your PC with git clone <https://github.com/jk-oster/lesson-3.git>. Navigate into the project folder lesson-3 and start the development server with npx vite β†’ click the link of the command output to open the development page.

</aside>

Feedback - Moderne Web Apps

Data Binding

observable & computed β‡’ "Synchroniserte Variablen" / "Reaktive Variablen"

on('<eventName>', () => action()) β‡’ Click Listener registrieren (UI β†’ Data)

<attributName>="${value}" ⇒ HTML Attribute mit Observable synchronisieren (Data→UI)

bind(observable) ⇒ Input-Daten mit Observable synchronisieren (Data→UI & UI→Data)

Data Binding Beispiel

import { Component, html, observable, on, bind } from "../../kwm-js";
export class ExampleComponent extends Component {
  // 1. Event listener - use on() helper
  doSomething = () => console.log('something');
  // 2. Input value binding - use observable() and bind()
  inputData = observable('Some initial text');
  // 3. Conditional visibility - use observable()
  isHidden = observable(false);
  // 4. Example todo for conditional classes
  todo = observable({ completed: false });
  render() {
    return html`
      <!-- 1. Event listener - use on() helper directly in template -->
      <button ${on('click', this.doSomething)}>Click me</button>
      
      <!-- 2. Input value binding - use bind() for two-way data binding -->
      <input type="text" ${bind(this.inputData)} />
      
      <!-- 3. Conditional visibility - use template interpolation with .value -->
      ${!this.isHidden.value && html`<div>This element is visible</div>`}
      
      <!-- Alternative: Always render but toggle hidden attribute -->
      <div ?hidden="${this.isHidden.value}">Toggleable content</div>
      
      <!-- 4. Text content binding - use template interpolation -->
      <div>${this.inputData.value}</div>
      
      <!-- 5. Conditional classes - use template expressions -->
      <div class="${this.todo.value.completed && 'text-line-through'}">
        Conditional class example
      </div>
      
      <!-- Conditional inline styles -->
      <div style="${this.todo.value.completed && 'text-decoration: line-through;'}">
        Conditional style example
      </div>
      
      <!-- Direct value as class (if inputData contains class name) -->
      <div class="${this.inputData.value}">
        Class from inputData
      </div>
      
      <!-- 6. Image src binding - use template interpolation -->
      <img src="${this.inputData.value}" alt="Dynamic image" />
      
      <!-- Use bind() for two-way binding (if editable) -->
      <input ${bind(this.inputData)} />
    `;
  }
}
customElements.define('example-component', ExampleComponent);

Data Binding Syntax β€” Framework Comparison

Feature kwmJS Angular React Vue.js
Conditional Rendering ${condition && '<component />'} <component *ngIf="condition" /> {condition && <Component />} <component v-if="condition" />
Loop / List Rendering ${items.map(item => '<component id="${item.id}" />')} <component ngFor="let item of items" [id]="item.id" /> {items.map(item => <Component key={item.id}>)} <component-for="item in items" :key="item.id" />
One-way Attribute Binding (Data→UI) attributename="${this.value}" [attributename]="value" attributename={value} :attributename="value"
Two-way Binding (Data→UI & UI→Data) bind(this.obsVariable) [(ngModel)]="property" value={property} onChange={e => setProperty(e.target.value)} v-model="property"
Event Binding on("click", method) (click)="method()" onClick={method()} @click="method()"
Declaring Reactive Variable this.num = observable(1) this.num = signal(1) const [num, setNum] = useState(1) const num = ref(1)
Computed values this.text = computed(()=> 'Result ' + this.obs.value + this.otherObs.value) this.text = computed(() => 'Result ' + this.someSignal() + this.someOtherSignal()) const text = useMemo(() => 'Result ' + someValue + someOtherValue, [someValue, someOtherValue]) const text = compute(()=>'Result ' + someRefValue.value + someOtherRefValue.value)

Programming Terms Glossary

Some terms in programming are confusing and there are often various expression that mean the same or a similar thing. So here is a quick overview of the most important ones: