不用vdom的lit框架学习3:代码结构初步解析

 这是lit框架的系列学习文章,跳转查看其他章节

  1. 不用vdom的lit框架学习1:安装和编译
  2. 不用vdom的lit框架学习2:挠头的web component(兼容性说明,必看)
  3. 不用vdom的lit框架学习3:代码结构初步解析
  4. 不用vdom的lit框架学习4:properties详细定义 

在补充了web component的一些基础性现状,明确了lit应用的一些适配现状之后,我们进一步来看看代码部分。

初始化安装之后,在目标目录会生成如下结构的初始化页面

│  index.html  //主页面文件
│  package.json
│  vite.config.js  //vite编译配置文件
│  
├─public  //html中直接调用的图片等其他媒体文件
│      vite.svg 
│      
└─src //参与编译的源码文件
    │  index.css //主css样式文件
    │  my-element.js //名为my-element的自定义模块
    │  
    └─assets  //在模块中引用的图片等其他媒体文件
            lit.svg 
            

index.html部分内容

index.html的内容其实就很简单了,主要是两个部分的内容。

首先在头部引用组件的js文件和样式文件

    <link rel="stylesheet" href="./src/index.css" />
    <script type="module" src="/src/my-element.js"></script>

然后就是像使用普通的a或者div元素一样使用这个自定义组件

<my-element>
   <h1>Vite + Lit</h1>
</my-element>

组件的定义

回过头我们再来看这个my-element.js文件的定义(ts部分请参考官网,官网主体是使用ts来写的,这里就换个思路,主用js):

import { LitElement, css, html } from 'lit'
import litLogo from './assets/lit.svg'

/**
 * An example element.
 *
 * @slot - This element has a slot
 * @csspart button - The button
 */
export class MyElement extends LitElement {
  static get properties() {
    return {
      /**
       * Copy for the read the docs hint.
       */
      docsHint: { type: String },

      /**
       * The number of times the button has been clicked.
       */
      count: { type: Number },
    }
  }

  constructor() {
    super()
    this.docsHint = 'Click on the Vite and Lit logos to learn more'
    this.count = 0
  }

  render() {
    return html`
      ………………
      <slot></slot>
      <div class="card">
        <button @click=${this._onClick} part="button">
          count is ${this.count}
        </button>
      </div>
      <p class="read-the-docs">${this.docsHint}</p>
    `
  }

  _onClick() {
    this.count++
  }

  static get styles() {
    return css`
      :host {
        max-width: 1280px;
        margin: 0 auto;
        padding: 2rem;
        text-align: center;
      }

      ………………
    `
  }
}

window.customElements.define('my-element', MyElement)

不重要的部分我已省略,大体上面的部分就是定义一个自定义组件需要的最小集内容,除了最开始的引用部分和类定义之外分为这几个部分:

  1. 类中定义properties(static get properties函数),properties是所有页面中需要参与动态渲染过程的变量的统称,用过vue的可类比vue的props,但范围更广,私有的内部的变量也需要在这里定义(类比vue的data),不定义的变量不能做到动态刷新页面的效果
  2. 类的初始化(constructor函数),除了调用super之外,最主要的内容是完成properties的默认值赋值,也就是说properties定义并不完成初始化值赋值,只有此时赋值才有用处。
  3. 类中渲染函数(render函数),返回一个html对象,其内容就是这个自定义组件对应的html代码。
  4. 类中定义功能函数(例子中为_onClick函数),组件对应的动态功能函数,可参考例子使用_作为函数名称开头,标识是内部函数。
  5. 类中定义样式(styles),自定义组建的自有样式,经实际使用发现,样式仅适用于本组件。
  6. 声明,在window.customElements里声明这个组件,名称和对应的类名称,有了这一行,index里面才可以使用<my-element>。

整体风格和react比较类似,和vue相比区别很大。

一些和普通html不太像的地方

有这么几个细节可能以后会逐步展开讲:

  • css定义中的:host指代本对象,在html中,自定义组件也是一级对象,因此可以设置自有的css属性。

  •  part="button",例子中html部分button的属性中有part="button"的定义,这表示该部分是调用方可以使用my-element::part(button)来自定义css样式的部分,当然最好也有对应的头部注释 @csspart button - The button

render函数的写法

今天主要展开讲render函数的写法

render() {
    return html`
      ………………
      <slot></slot>
      <div class="card">
        <button @click=${this._onClick} part="button">
          count is ${this.count}
        </button>
      </div>
      <p class="read-the-docs">${this.docsHint}</p>
    `
  }

从生成的示例文件可以看到,render函数主要返回了一个html模板,写法是固定使用html开头,后跟(``)包裹的模板字符串,模板中以${和}括起来的部分是动态部分,其他则是静态html。

动态部分主要分为两个部分。

一个是渲染的变量值,比如例子中的count is ${this.count},这个例子主要展示了两种变量,一个是内部变量this.count,该值主要和onClick函数配合,用于内部计数;另外一个是docsHint,主要是外部可传入的附加内容,可以通过修改index.html来试试

    <my-element docsHint="中文Lit教程">
      <h1>Vite + Lit</h1>
    </my-element>

另外就是回调函数的声明,例如例子中的@click=${this._onClick},vue的同学注意了,不需要多个引号。

这个示例通过yarn dev运行之后,点击按钮会动态数值进行增长

 下一步工作

了解到这些信息之后,我们对于lit的使用有了一个初步的概念,从我们自己的角度出发,我们做了以下的工作,这个过程应该是比较通顺的:

1)替换render中的静态部分内容

2)尝试增加更多的properties

3)尝试将新的properties用在render中

以上两步不要搞反了,如果render中用到了没有定义的properties,是不会触发动态渲染的

大家可以初步设想一个页面目标,尝试将示例页面进行上述修改来练手,下一讲将properties的详细定义方法。

猜你喜欢

转载自blog.csdn.net/baijiafan/article/details/129749707