Lit 集成 tailwindcss 以及如何在 Lit 元素中使用 css/scss 样式文件

525 阅读2分钟

Lit.png

关于 Lit 和 tailwindcss

Lit

它是一个轻量级、高性能的 Web 组件库,由 Google 团队开发并维护。它旨在帮助开发者快速构建高效、可复用的 Web 组件,适用于现代 Web 应用程序的开发。核心库非常小(约 5 KB),加载速度快,性能优异,适合构建高性能的 Web 应用。在github上能看到这个库的开发速度非常快,并且维护频率也相当高。

tailwindcss

Tailwind CSS 是一个功能优先的 CSS 框架,旨在帮助开发者快速构建现代化的用户界面。与传统的 CSS 框架不同,Tailwind 不提供预定义的组件,而是提供了一系列低级别的实用类(utility classes),允许开发者直接在 HTML 中通过组合这些类来构建自定义设计。

在 Lit 中使用 tailwindcss

这里列举出了vite 中 tailwindcss@4 安装的方法,tailwindcss@3 的安装方法详见 tailwindcss@3 官网

安装

# pnpm
pnpm add tailwindcss @tailwindcss/vite

# yarn
yarn install tailwindcss @tailwindcss/vite

# npx
npx install tailwindcss @tailwindcss/vite

css文件

在css文件中 ./tailwind.global.css

@import "tailwindcss";

自定义扩展 Lit 元素类

在公用元素类 custom-lit-element.ts

import type { LitElement } from 'lit'
import { adoptStyles, unsafeCSS } from 'lit'

// 上述 样式文件
import style from '../styles/tailwind.global.css?inline'

// 转换为 Lit 可使用的 css 样式表
const stylesheet = unsafeCSS(style)

/**
 * tailwind css 注入
 * @param superClass
 * @constructor
 */
export function TW<T extends LitMixin>(superClass: T): T {
  return class extends superClass {
    connectedCallback() {
      super.connectedCallback()
      adoptStyles(this.shadowRoot!, [stylesheet])
    }
  }
}

// 更多的上层功能代码可以写到此处,与TW实现一致
 
/**
 * 自定义扩展了 Lit 原生的组件
 */
export const CustomLitElement = TW(LitElement)

declare global {
  export type LitMixin<T = unknown> = new (...args: any[]) => T & LitElement
}

在 Lit 组件中使用

组件./Button.ts

import { CustomLitElement } from './custom-lit-element'
import { css, html } from 'lit'
import { customElement, property } from 'lit/decorators.js'

type Size = 'default' | 'small' | 'large'

type Theme = 'leight' | 'dark'

@customElement('custom-button')
export class CustomButton extends CustomLitElement {
  @property()
  size?: Size = 'default'

  @property()
  type?: Theme

  // css
  static styles = css``

  // 在渲染函数中可以写 tailwindcss 中的样式类
  render() {
    return html`
      <button class="h-[20px] flex items-center color-[red]" >
        <slot></slot>
      </button> 
    `
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'custom-button': CustomButton
  }
}

Lit 元素引用 css/scss 样式文件

样式文件

独立的样式文件 ./button.scss


@use 'sass:map';

@use 'common/var' as *;
@use 'mixins/button' as *;
@use 'mixins/mixins' as *;
@use 'mixins/utils' as *;
@use 'mixins/var' as *;

// 更多样式

元素引用

元素 ./Button.ts

import { CustomLitElement } from './custom-lit-element'
import stylesheet from './button.scss?inline'
import { adoptStyles, css, html, unsafeCSS } from 'lit'
import { customElement, property } from 'lit/decorators.js'

type Size = 'default' | 'small' | 'large'

type Theme = 'leight' | 'dark'

@customElement('custom-button')
export class CustomButton extends CustomLitElement {
  @property()
  size?: Size = 'default'

  @property()
  type?: Theme

  // css
  static styles = css``
  
  
  // 核心代码
  constructor() {
    super()
  }
  // 注入外部样式文件
  connectedCallback() {
    super.connectedCallback()
    adoptStyles(this.shadowRoot!, [unsafeCSS(stylesheet)])
  }
  

  // 在渲染函数中可以写 tailwindcss 中的样式类
  render() {
    return html`
      <button class="h-[20px] flex items-center color-[red]" >
        <slot></slot>
      </button> 
    `
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'custom-button': CustomButton
  }
}


Lit 使用感想

Lit 的一些api 和模版语法跟 Vue 相似,但是其中又有一些react的影子,底层使用了更新的 web-components。像是集大成者的一种框架,希望 Lit 能在 google 的支撑下有更好的发展吧。