zoukankan      html  css  js  c++  java
  • Stencil 基础

    Stencil

    一个轻量化,渐进式编译器,注意,不是框架。

    使用 TypeScript 进行所有操作,这是一个门槛,有一定技术门槛要求。

    PS:个人强烈推荐所有的前端同学都学习,或至少了解这个超集语言。

    生命周期

    • componentWillLoad
    • componentDidLoad
    • componentWillUpdate
    • componentDidUpdate
    • componentDidUnload

    几乎所有框架都有的,这里精简到 5 个,不再做过多赘述。

    需要注意的是生命周期在父子组件的传递顺序,这个是常规理解顺序(a 套着 b,b 套着 c):

    1. cmp-a - componentWillLoad()
    2. cmp-b - componentWillLoad()
    3. cmp-c - componentWillLoad()
    4. cmp-c - componentDidLoad()
    5. cmp-b - componentDidLoad()
    6. cmp-a - componentDidLoad()

    装饰器

    • Component
    • Prop
    • Watch
    • State
    • Method
    • Element

    Component

    与 Angular 类似,用来装饰当前类为组件类,并且可以提前声明相关元数据。

    @Component({
    	tag: 'todo-list', // 标签名
    	styleUrl: 'todo-list.scss', // 样式链接,可使用 styleUrls 来插入数组
    	host: { // 当前组件配置
    	    theme: 'todo', // class
    	    role: 'list' // 参数
    	}
    })
    

    使用:

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

    Prop

    声明传入参数,可以通过元数据 @Prop({ mutable: true })@Prop({ reflectToAttr: true }) 使其可变动与反射到绑定源上。

    @Prop() prop1: any
    @Prop() prop1: number = 1 // 设置默认值
    @Prop({ mutable: true }) prop2: any // 可变动
    @Prop({ reflectToAttr: true }) prop3: any // 反射
    

    使用注意:html 文件中使用要使用 a-b 连字符,组件中使用 aB 驼峰标识。

    Watch

    常规的观察装饰器,可以用来监听某个 Prop 的变化,用法:

    @Watch('prop1')
    watchHandler(newValue: any, oldValue: any) {
    	// todo...
    }
    

    State

    内部状态,跟 React 的 State 一个意思,不过更新不用使用 setState ,直接修改即可。

    @State() state1: number = 1
    

    Method

    函数装饰器,用来说明这是个函数:

    @Method()
    method1() {
    	// todo...
    }
    

    Element

    比较稀奇的装饰器,可以用来获取当前组件的 DOM 实例,进行常规 DOM 操作,当前,内部声明的也已经绑定到实例上了,如下:

    @Element() ele: HTMLElement
    

    使用:

    this.todoListEl.classList.add('active')
    

    事件

    两个相关装饰器:Event,EventEmitter,事件与事件发射器。

    Event

    发射:

    import { Event, EventEmitter } from '@stencil/core';
    
    export class TodoList {
    
      @Event() todoCompleted: EventEmitter;
    
      todoCompletedHandler(todo: Todo) {
        this.todoCompleted.emit(todo);
      }
    }
    

    监听:

    import { Listen } from '@stencil/core';
    
    export class TodoApp {
    
      @Listen('todoCompleted')
      todoCompletedHandler(event: CustomEvent) {
        console.log('Received the custom todoCompleted event: ', event.detail);
      }
    }
    

    监听原生

    @Listen('body:scroll')
    handleScroll(ev) {
      console.log('the body was scrolled', ev);
    }
    
    @Listen('keydown')
    handleKeyDown(ev){
      if(ev.keyCode === 40){
        console.log('down arrow pressed')
      }
    }
    
    @Listen('keydown.up')
    handleUpArrow(ev){
      console.log('will fire when up arrow is pressed');
    }
    

    目前支持的按键:

    • enter
    • escape
    • space
    • tab
    • left
    • up
    • right
    • down

    不支持的考虑使用 keyCode 处理。

    JSX 监听

    这个牛逼了……还是上面那个 todoList,然后不用 @Listen,直接在组件上 on 即可:

    <todo-list onTodoCompleted={ev => this.someMethod(ev)}></todo-list>
    

    我下巴都掉了……N 久不用 React 了,这么先进?


    数据响应

    有点尴尬,也有点强势。

    不支持监听数组(对象一样)本身变动,意思说:

    改动数组本身,不会引起响应,比如 pop、push 啦,统战思想就是,换新数组。

    let arr = [1, 2, 3]
    arr.push(4) // 不响应
    arr = [...arr, 4] // 响应
    

    明白了?虽然觉得挺奇怪,但是好在简单,不用去记哪些能引起,哪些不能引起……


    JSX

    熟悉的同学可以跳过。

    事件绑定两种方式

    render() {
        return (
    		<button onClick={ (event: UIEvent) => this.handleClick(event)}>Click Me!</button>
    	);
    }
    
    render() {
        return (
    		<button onClick={this.handleClick.bind(this)}>Click Me!</button>
    	)
    }
    

    插入 html 代码

    <div innerHTML={svgContent}></div>

    ref

    <input type="text" ref={(el: HTMLInputElement) => this.textInput = el} />


    样式

    1. Shadow DOM
    2. 样式变量

    Shadow DOM

    这玩意是一组 API,功能大体是用来封装 Web Component 到局部,类似 Vue 等的 scoped 功能。

    Stencil 默认不使用 Shadow DOM,开启如下:

    @Component({
      tag: 'shadow-component',
      styleUrl: 'shadow-component.scss',
      shadow: true
    })
    export class ShadowComponent {
    
    }
    

    就是 Component 装饰器一个 shadow 的元数据。

    此时获取组件内的 DOM 实例则使用:this.el.shadowRoot.querySelector()

    之前使用的 css 文件声明:

    my-element {
      div {
        background: blue;
      }
    }
    

    可以改为:

    :host {
      div {
        background: blue;
      }
    }
    

    样式变量

    在根路径下的 stencil.config.js 文件内配置:globalStyle: 'path/to/variables.css,内容类似下方:

    :root {
      --app-primary-color: #488aff;
    }
    

    注意 :root 声明,然后其他组件使用如下:

    h1 {
      color: var(--app-primary-color)
    }
    

    配置插件

    css 预编译器需要声明插件才能使用,比如 sass、less、stylus 以及 postcss。

    stencil.config.ts

    import { less } from '@stencil/less'
    
    exports.config = {
      plugins: [
        less()
      ]
    }
    

    全局引入

    stencil.config.ts

    globalScript: 'src/global/app.ts'


    实例 Demo:npm init stencil 选择 ionic 即可。

  • 相关阅读:
    【LeetCode】Validate Binary Search Tree
    【LeetCode】Search in Rotated Sorted Array II(转)
    【LeetCode】Search in Rotated Sorted Array
    【LeetCode】Set Matrix Zeroes
    【LeetCode】Sqrt(x) (转载)
    【LeetCode】Integer to Roman
    贪心算法
    【LeetCode】Best Time to Buy and Sell Stock III
    【LeetCode】Best Time to Buy and Sell Stock II
    CentOS 6 上安装 pip、setuptools
  • 原文地址:https://www.cnblogs.com/ZweiZhao/p/9817591.html
Copyright © 2011-2022 走看看