Getting started with StencilJS

A few weeks ago in Polymer Summit 2017, Max Lynch and Adam Bradley introduced a new compiler which creates native Web Components. The compiler is called Stencil and it combines a lot of aspects from known libraries and frameworks such as React and Angular. In this article, we will familiarize ourselves with the basics of Stencil.

Stencil borrows a lot of concepts from existing frameworks. Some of these concepts include:

– Virtual DOM

– Reactive data-binding

– TypeScript

– JSX

Experience with Angular and React is not necessary but could really go a long way when creating our Stencil Project.

This article also shows, with examples, how these concepts are applied in a Stencil component.

Creating a Stencil Project

Making sure that we already have npm installed, we execute the following in our command line:

# Clone the Github reo
    git clone https://github.com/ionic-team/stencil-app-starter my-first-stencil-project 

    # Move into the repo
    cd my-first-stencil-project

    # Remove original remote URL
    git remote rm origin

    # Install npm dependencies
    npm install

And we are good to go. Our project should look like this:

Creating a Stencil Component

Stencil components are built using JSX and TypeScript. Therefore, familiarity with these two technologies will be very important before going further. To create our first Stencil component, we add a new file with a .tsx
extension. For example, create a collapsible-panel
folder in the src/components
directory then add collapsible-panel.tsx
in the folder. Insert the following code:

import {Component, Prop, State} from '@stencil/core';

    @Component({
      tag: 'collapsible-panel',
      styleUrl: 'collapsible-panel.scss'
    })
    export class CollapsiblePanel {
      @Prop() title: string;
      @State() collapsed: boolean;

      toggle() {
          this.collapsed = !this.collapsed;
      }

      render() {
        return (
            
); } }

Let’s walk through the bit of code we just wrote:

  • First of all, the file’s extension is .tsx
    which means that the code is written in TypeScript and JSX.
  • In order to create a Stencil component we use the Component
    decorator which configures the class with the selector in the DOM and with the scoped style. Decorators are basically functions that extend what is being decorated. Therefore, in this case, the Component
    decorator extends and adds more functionality to the CollapsiblePanel
    class. We will visit some of the existing decorators later in this article.

  • Then we create a class for the component and export it. In our class, we are using two other Stencil decorators — ** Prop
    and State
    . Prop
    indicates a property that the component will get as a component attribute while State
    is an inner state of the component.

  • The component gets to work in the render
    function because that is where we tell our compiler how to render the component. Similarities with other frameworks can be noticed here — such as the use of curly brackets for binding the onClick
    and hidden
    events (like JSX in React) and the slot
    element which is used to indicate that the content will be provided by the component’s user (like transclusion in Angular).

To style our component, we create a file collapsible-panel.scss
, add our style to it and insert it in our src/components/collapsible-panel
directory:

collapsible-panel {
      display: block;
      border: black dashed 1px;
    }

    #header {
      background: red;
      color: white;
      cursor: pointer;
      padding: 2px;
    }

We then update **our ** index.html
file with our collapsible-panel
element:

    
    

    
    
      
  • Hi! I'm Stencil
  • I work with Web Components

Lastly we register our component in the stencil.config.js
file:

exports.config = {
      bundles: [
        { components: ['collapsible-panel'] }
      ]
    };

    exports.devServer = {
      root: 'www',
      watchGlob: '**/**'
    }

If we run the app using the npm start
command, we should see the following web page with a collapsible bar:

Decorators

Stencil is useful when it comes to building interactive components. There are a number of decorators such as Component
, Props
, State
and Event
that help achieve this. Let’s take a look at how these decorators are used.

Component Decorator

Our component must be decorated with an @Component()
decorator from the @stencil/core
package. A HTML tag
name and a styleUrl
which contains our style sheet are provided for the component. If multiple stylesheets are wanted then they can be referenced by styleUrls
instead . For our stylesheet, we use Sass. Create a file with the .``scss
extension.

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

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

Prop Decorator

Props are custom properties that we can provide values for. These are used to pass down data from parent components to any child component. The @Prop()
decorator is used by a component to declare the Props it expects to receive. Props can be in different forms: they can be a number
, a string
, a boolean
, an Object
or an Array
. When a member decorated with the @Prop()
decorator is set, the component re-renders by default.

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

Component State

We now need to track the state of our component’s internal data. To do this we use the @State()
decorator. The @State()
decorator manages our component’s internal data. This implies that a user cannot modify the property from outside the component, but the component can modify it however it sees fit. Any changes to an @State()
property will cause the components render function to be called again.

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

    ...
    export class ShoppingList {
      @State() completedShoppings: Shopping[];

      completeShopping(shopping: Shopping) {
        // This will cause our render function to be called again
        this.completedShoppings = this.completedShoppings.filter(item => item.bought == true);
      }

      render() {
        //
      }
    }

Event Decorator

At some point in our app, our components will start emitting data and events. To achieve this, we use the Event Emitter decorator written as @Event()
.

import { Event, EventEmitter } from '@stencil/core';

    ...
    export class ShoppingList {

      @Event() shoppingCompleted: EventEmitter;

      shoppingCompletedHandler(shopping: Shopping) {
        this.shoppingCompleted.emit(shopping);
      }
    }

The code above will dispatch a custom DOM event called shoppingCompleted
.

To handle events dispatched from @Events
, we use the @``Listen()
decorator in the listening component. In the example below, let’s assume that a child component, ShoppingList
, emits a shoppingCompleted
event using the EventEmitter
.

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

    ...
    export class ShoppingBag {

      @Listen('shoppingCompleted')
      shoppingCompletedHandler(event: CustomEvent) {
        console.log('Received the custom shoppingCompleted event: ', event.detail);
      }
    }

Handlers can also be registered for an event on a specific element. This is good for listening to

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

    ...
    export class ShoppingList {

      @Listen('button:click')
      handleClick(ev) {
        console.log('the button was clicked', ev);
      }
    }

Conclusion

It’s really exciting to see where the web is headed. The ability to create web components which can be shared with any framework and library is going to improve how we build for the web. For a deeper understanding of how Stencil works, especially with advanced concepts such as server side rendering and service workers, you can check out the Stencil Documentation here.

The post Getting started with StencilJS appeared first on Pusher Blog.

稿源:JSFeeds (源链) | 关于 | 阅读提示

本站遵循[CC BY-NC-SA 4.0]。如您有版权、意见投诉等问题,请通过eMail联系我们处理。
酷辣虫 » 前端开发 » Getting started with StencilJS

喜欢 (0)or分享给?

专业 x 专注 x 聚合 x 分享 CC BY-NC-SA 4.0

使用声明 | 英豪名录