An open API service indexing awesome lists of open source software.

https://github.com/anh-ld/nho

๐Ÿ“Œ 1KB Web Component Abstraction
https://github.com/anh-ld/nho

1kb custom-component lightweight web-component

Last synced: 8 months ago
JSON representation

๐Ÿ“Œ 1KB Web Component Abstraction

Awesome Lists containing this project

README

          

## ๐Ÿ“Œ Nho

Nho (`nhแป` | `small` in `Vietnamese`) is a tiny library designed for easy Web Component development.

### Why Nho?

- Writing a Web Component (WC) using vanilla JavaScript can be such tedious. Alternatively, popular WC libraries can be overkill and overweighted (4KB+) for creating small components like a `"Buy now" button` or a `cart listing`.

- `Nho` simplifies the process by staying lightweight, removing unnecessary APIs, and using a simple DOM diffing algorithm.

### Features

- `1.3KB` gzipped.
- Simple API inspired from `Vue`.

### Example
- [album list](https://nho-example.netlify.app/) - [source](./example)

### Limitation

- In order to stay small, `Nho` skips few advanced features found in popular front-end frameworks like `key`, `Fragments`, `memo`. The DOM diffing algorithm is somewhat basic, but it is fast enough for small projects. If your components become too complex, consider other options.

### Installation

#### using `npm`
First, run

```
npm install nho
```

then
```js
import { Nho } from 'nho';
class MyCounterChild extends Nho {}
```

#### using `CDN`
First, add `script` to the `html` file
```html

```

then, add `script` to the `html` file

```html

let Nho = nho.Nho;
class MyCounterChild extends Nho {}

```

### Usage

```js
/* main.js */

/* declare global style. Styles will be injected to all Nho Elements */
Nho.style = `
.box {
background: blue;
color: yellow;
}
`

class MyCounterChild extends Nho {
render(h) {
/* bind value from props */
return h`

Child: ${this.props.count}
`
}
}

class MyCounter extends Nho {
setup() {
/* this method runs before mount */

/* create component state using "this.reactive", state must be an object */
this.state = this.reactive({ count: 1 });

/* only use ref for storing DOM reference */
this.pRef = this.ref();

/* effect */
this.effect(
// effect value: fn -> value
() => this.state.count,
// effect callback: fn(old value, new value)
(oldValue, newValue) => {
console.log(oldValue, newValue)
}
)
}

onMounted() {
/* this method runs after mount */
console.log('Mounted');
}

onUpdated() {
/* this method runs after each update. */
console.log('Updated');

/* P tag ref */
console.log('P Ref', this.pRef?.current);
}

onUnmounted() {
/* this method runs before unmount */
console.log('Before unmount');
}

addCount() {
/* update state by redeclaring its key-value. Avoid updating the whole state. */
this.state.count += 1;
}

render(h) {
/* this method is used to render */

/*
JSX template alike
- Must have only 1 root element
- Bind state / event using value in literal string
- Pass state to child element using props with 'p:' prefix
*/
return h`


Name: ${this.state.count}


Add count


`
}
}

customElements.define("my-counter", MyCounter);
customElements.define("my-counter-child", MyCounterChild);
```

```html
/* index.html */

```

### Notice
- **Avoid** using these below properties inside Nho Component since they are reversed Nho's properties.

Element properties

```
_op, _ef, _ev, _sr, _ga, _nm, _sc, _p, _u, _h, _e, _t
```

```
setup, onMounted, onUnmounted, onUpdated, effect, ref, reactive, render
```

Class properties
```
_c, style
```

### How it works

- It's better to dive into the code, but here is a quick sketch about how `Nho` works.

![How Nho works](./hiw.webp)

### Mentions

- [Frontend Focus's #651 issue](https://frontendfoc.us/issues/651)