Stencil : Decorators

Component Decorator

แต่ละ Stencil component จะต้องขึ้นต้นด้วย @Component() decorator เสมอ โดย import มาจาก @stencil.core package ซึ่งภายใต้ @Component() decorator สามารถกำหนด tag name และ styleUrl ของ component

import { Component } from '@stencil/core';

@Component({
  tag: 'todo-list',
  styleUrl: 'todo-list.scss'
})
export class TodoList {
  ...
}

@Component() decorator ให้ความสามารถในการกำหนด CSS classes และ attributes บน componnet ที่สร้างโดยใช้ host option ดังนี้

import { Component } from '@stencil/core';

@Component({
  tag: 'todo-list',
  styleUrl: 'todo-list.scss',
  host: {
    theme: 'todo',
    role: 'list'
  }
})

เมื่อใช้งาน component ตัวนี้ ก็จะมีการกำหนดค่า class เป็น todo และกำหนด role attribute ให้อัตโนมัติ

<todo-list class='todo' role='list'></todo-list>

 

Prop Decorator

@Prop() decorator ใช้ระบุ attribute หรือ properties สำหรับ element ที่ผู้พัฒนาสามารถกำหนดค่าให้กับ component นั้นได้  เนื่องจาก Children component จะไม่สามารถเข้าถึง properties หรือ reference ของ parent component ได้จึงใช้ Props ในการผ่านข้อมูลจาก parent มาสู่ child และเมื่อใดก็ตามที่ค่าของ Props เปลี่ยนแปลงจะทำให้ component ทำการ re-render

type ของ Props ที่รองรับมีหลากหลาย ไม่ว่าจะเป็น number, string, boolean หรือแม้กระทั่ง Object หรือ Array

import { Prop } from '@stencil/core';
...
export class TodoList {
  @Prop() color: string;
  @Prop() favoriteNumber: number;
  @Prop() isSelected: boolean;
  @Prop() myHttpService: MyHttpService;
}

ภายใน function ใน TodoList class สามารถเรียกใช้งาน Props ผ่าน this operator

logColor() {
  console.log(this.color)
}

สำหรับการใช้ภายนอก ใน HTML การกำหนดค่าทำได้โดย set ค่าให้ attributes ของ component tag โดยใช้ dash-case  เช่น Prop favoriteNumber ใช้ attribute favorite-number

<todo-list color="blue" favorite-number="24" is-selected="true"></todo-list>

สำหรับการใช้ใน JSX การกำหนดค่าทำได้โดย set ค่าให้ attributes ของ component tag โดยใช้ camelCase

<todo-list color="blue" favoriteNumber="24" isSelected="true"></todo-list>

Prop สามารถเรียกใช้งานผ่านทาง element ของ  javascript

const todoListElement = document.querySelector('todo-list');
console.log(todoListElement.myHttpService); // MyHttpService
console.log(todoListElement.color); // blue

 

Component State

@State() decorator ใช้ในการจัดการ internal data ของ component ซึ่งผู้ใช้ไม่สามารถแก้ไขข้อมูลจากภายนอก component  เมื่อข้อมูลมีการเปลี่ยนแปลง จะทำให้ component ทำการ re-render เช่นเดียวกับ Prop

import { State } from '@stencil/core';

...
export class TodoList {
  @State() completedTodos: Todo[];

  completeTodo(todo: Todo) {
    // This will cause our render function to be called again
    this.completedTodos = [...this.completedTodos, todo];
  }

  render() {
    //
  }
}

 

Element Decorator

@Element() decorator ใช้ในการเข้าถึง host element ภายใน class instance โดย return type คือ HTMLElement  ทำให้สามารถใช้ standard DOM methods/events ได้

import { Element } from '@stencil/core';

...
export class TodoList {

  @Element() todoListEl: HTMLElement;

  addClass(){
    this.todoListEl.classList.add('active');
  }
}

 

อ้างอิง : https://stenciljs.com/docs/decorators