0%

今天我们一起来学习一下如何使用TypeScript创建Lit Element应用,如果还不熟悉什么是Lit Element,可以看一下这里

话不多说,直接上干货。

前提条件

在开始之前,请确保你已经安装了以下软件:

  • Node.js
  • npm - 一般来说,安装了Node.js,npm也就顺带安装好了。

创建项目

我们使用时下最流行的Vite来创建一个新的项目,Vite是一个快速的前端构建工具,可以帮助我们快速搭建开发环境。

打开命令行,运行以下命令:

1
2
3
4
npm create vite@latest my-lit-app-typescript --template vanilla-ts
cd my-lit-app-typescript
npm install
npm install lit

添加Lit Element组件

src目录下创建一个新的文件夹components,然后在该文件夹下创建一个新的文件my-element.ts,并添加以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { LitElement, html, css } from 'lit';
import { customElement } from 'lit/decorators.js';
import { property } from 'lit/decorators.js';

@customElement('my-element')
export class MyElement extends LitElement {
@property({ type: String }) name = 'World';

static styles = css`
h1 {
color: blue;
}
`;

render() {
return html`<h1>Hello, ${this.name}!</h1>`;
}
}

在上面的代码中,我们创建了一个名为my-element的自定义元素,它继承自LitElement。我们使用了@customElement装饰器来定义这个元素,并使用@property装饰器来定义一个属性name

运行项目

使用VSCode打开项目,运行以下命令启动开发服务器:

1
npm run dev

不出意外,你会遇到@customElement("my-element")无法识别的错误:

1
Uncaught SyntaxError: Invalid or unexpected token (at my-element.ts:3:1)

这是因为@customElement是装饰器语法,这个语法还未被浏览器正式支持,目前处于state 3,在未来的版本中可以支持,所以暂时需要在tsconfig.json中添"experimentalDecorators": true配置才行。关于Decorator的更多信息,可以看这里

1
2
3
4
5
6
7
{
"compilerOptions": {
// ...
"experimentalDecorators": true,
// ...
}
}

再次运行程序,不出意外,你会遇到如下错误:

1
following properties on element my-element will not trigger updates as expected because they are set using class fields: name. Native class fields and some compiled output will overwrite accessors used for detecting changes. See https://lit.dev/msg/class-field-shadowing for more information

只需要在tsconfig.json中添加如下配置即可:

1
2
3
4
5
6
7
{
"compilerOptions": {
// ...
"useDefineForClassFields": false
// ...
}
}

再次运行程序,这次页面上可以看到Hello, Philip了,Happy Coding!

Lit Element是一款基于Web Component的轻量级库,今天来学习一下如何在原生JavaScript中使用Lit Element

使用Vite创建项目

首先我们使用Vite创建一个原生JavaScript项目,在命令行下运行如下命令:

1
npm create vite@latest my-lit-element-app --template vanilla

执行这条命令后,Vite会询问用户选择一个模板,我们选择vanilla模板。接下来,Vite会询问我们使用JavaScript还是TypeScript,我们选择JavaScript

然后执行如下命令进入项目目录并安装依赖。

1
2
cd my-lit-element-app
npm install

安装Lit Element

运行以下命令来安装lit

1
npm install lit

创建Lit Element组件

在项目的src目录下创建一个新的文件夹components,然后在该文件夹下创建一个新的文件my-element.js,并添加以下代码:
在下面的代码中,我们创建了一个名为my-element的自定义元素,它继承自LitElement

1
2
3
4
5
6
7
8
9
10
import { LitElement, html, css } from 'lit';
import { customElement } from 'lit/decorators.js';
import { property } from 'lit/decorators.js';

class MyElement extends LitElement {
render() {
return html`<h1>Hello, ${this.name}!</h1>`;
}
}
customElements.define('my-element', MyElement);

使用Lit Element组件

src/main.js中导入我们刚刚创建的组件,并在页面中使用它:

1
2
3
4
5
6
7
import './style.css';
import './components/my-element.js';

const app = document.querySelector('#app');
app.innerHTML = `
<my-element></my-element>
`;

在上面的代码中,我们在页面中使用了my-element组件,使用web component就是使用普通的html标签一样。

运行项目

删除项目中的src/counter.js文件,因为我们不需要它们。
最后,在命令行中运行以下命令来启动开发服务器:

1
npm run dev

然后在浏览器中打开http://localhost:5173,页面上显示Hello, world!

Vanilla JavaScript中无法使用装饰器

需要注意的是,如果你使用原生JS开发Lit Element组件,是不能使用装饰器的,至少目前的JS还不支持,比如下面这些装饰器都无法使用:

  • @customElement
  • @property
  • @state

如果你使用了这些装饰器,浏览器会报错,以@customElement为例,报错信息如下:

1
my-element.js:5 Uncaught SyntaxError: Invalid or unexpected token (at my-element.js:5:1)

一个代替的方案是使用如下的方式:下面的代码中,我们使用了static properties来定义属性,使用constructor来初始化属性。
需要注意的是@click - 这是Lit的模板中的事件绑定语法,而非装饰器,所以@click是可以被原生JS支持的,有Lit在运行是转义为addEventListener来实现的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import { LitElement, html } from 'lit';

class MyElement extends LitElement {
static properties = {
name: { type: String }, // 替代 @property({ type: String }) name = 'Philip';
count: { state: true }, // 替代 @state() private count = 0;
};

constructor() {
super();
this.name = 'Philip';
this.count = 0;
}

render() {
return html`
<p>Hello, ${this.name}!</p>
<button @click=${() => this.count++}>Count: ${this.count}</button>
`;
}
}

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

@是Lit用作事件绑定的语法,除了@click,还有@input@change@submit等事件绑定语法。

今天我们来学习一下如何在React项目中使用Lit Element,Lit Element是一个轻量级的Web Component库,因为基于标准的Web Component API, 所以它可以在任何支持Web Component的框架中使用,比如React、Vue、Angular等。

使用Vite创建React项目

首先使用Vite创建React项目,在命令行下运行如下命令:

1
npm create vite@latest lit-app-react-ts --template react-ts

提示framework的时候选择react,语言选择typescript

安装Lit Element

接下来运行以下命令来安装lit

1
npm install lit

更改tsconfig设置

tsconfig.json中添加以下配置:

1
2
3
4
5
6
{
"compilerOptions": {
"experimentalDecorators": true,
"useDefineForClassFields": false,
}
}

创建Lit Element组件

src目录下创建一个components目录,然后在components目录下创建一个my-element.ts文件,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { LitElement, css, html } from 'lit';
import { customElement, property } from 'lit/decorators.js';

@customElement('my-element')
export class MyElement extends LitElement {
@property({ type: String }) name = 'World';

static styles = css`
:host {
display: block;
padding: 16px;
color: var(--my-element-text-color, black);
}
`;

render() {
return html`<p>Hello, ${this.name}!</p>`;
}
}

在App.tsx中使用Lit Element组件

src/App.tsx中引入并使用my-element组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import './App.css';
import './components/my-element.ts';

function App() {

return (
<>
<h1>Hi</h1>
<my-element name="World"></my-element>
<p>This is a paragraph</p>
</>
)
}

export default App

运行项目

1
2
3
cd my-react-lit-app
npm install
npm run dev

公司的项目是基于React,今天周末闲着没事用Vite搭建了一个React项目,在运行的时候,突然发现,即使typescript类型匹配,程序竟然也没有报错,于是突发奇想,能不能在类型不匹配的时候停止运行并报错呢?

代码很简单,首先我定义了一个Card组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import React, {ReactNode} from 'react'

interface CardProps {
title: string;
content: string;
children?: ReactNode;
}

export function Card(props: CardProps) {
return (
<div className="card">
<h2>{props.title}</h2>
<p>{props.content}</p>
<p>{props.footer}</p>
{props.children}
</div>
)
}

在返回的组件中,我故意使用了一个CardProps中没有的属性 - footer。此时运行程序,你会发现一切正常!
这有点不合逻辑呀,应该报错才是,于是对着AI一番操作,找到如下方法:

首先安装vite-plugin-checker

1
npm install --save-dev vite-plugin-checker

然后在vite.config.ts中添加如下配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
import {defineConfig} from 'vite'
import react from '@vitejs/plugin-react'
import checker from 'vite-plugin-checker';

// https://vite.dev/config/
export default defineConfig({
plugins: [
react(),
checker({
typescript: true,
}),
],
})

再次运行npm run dev,你会发现控制台给出类型不匹配的报错了, 浏览器中的页面也给出了报错,这才是我想要的结果呀!

有的建议在tsconfig.json中开启strict: true模式,其实和这个选项无关。typescript是静态类型检查,只在编译时有作用,运行时已经没有typescript了,所以只能靠打包工具来控制是否报错,比如vite或者webpack等。

React中有很多方式书写CSS样式,内联样式,CSS模块,CSS-in-JS等。下面总结一下。

1. 内联样式

内联样式是最简单直观的方式,样式直接写到组件中。这种方式只适合比较简单的样式,如果样式比较复杂,建议采用CSS Module的方式,这样能够使组件文件更加清爽。

下面是一个内联样式的例子,divh1的样式直接写在组件中。

Read more »

MacOS上的快捷键特别多,用好这些快捷键能极大的提高我们的工作效率。

触控板手势

在Mac上用好触控板手势,基本上可以脱离鼠标进行工作。话不多少,直接上图,图片来自知乎。
mac-gesture-1
mac-gesture-2
mac-gesture-1

MacOS 按键符号

MacOS上没有Windows3统上的Ctrl健(使用Command健代替),而且多了一个Windows系统上没有的Option键。

如果你看到的快捷键是Ctrl,那么在Mac上应该替换为Command,如果是Alt,那么在Mac上应该替换为Option。下面是MacOS上一些常用的按键符号:

Read more »

VSCode是如今市面上最流行的IDE了,用好VSCode是每一个前端程序员必备的技能,而VSCode又有大量的快捷键可以使用,下面是一些常用的VSCode快捷键。

说明

在MacOS上请将Ctrl替换为CommandAlt替换为Option

Read more »

2025-04-08

今天是2025年4月8日,星期二,天气晴。
今天王军来大连出差,住中山区新文园大酒店,我正好失业在家,于是就去找他喝酒,晚上是在钱库里自助吃的。十多年没见了,有很多话要说,家长里短的聊了一大通,他第二天还要培训,而我再过一天也要去天津渣打银行报道,所以没有喝太多酒!
期待下次相聚。

Read more »

概述

CSS中隐藏元素的方法有很多,每种方式都有其适用的场景,在合适的场景下使用合适的方式,能使编程事半功倍。

1. display: none

display: none是最常用的隐藏元素的方法,它会将元素从文档流中移除,元素不占据空间。

1
2
3
.hidden {
display: none;
}
1
<div class="hidden">This is a hidden element</div>
Read more »

body宽度设置为100%,为啥还有横向滚动条?

问题现象:

这是一个非常简单的例子,创建一个html文件,设置body的宽度为100%,然后在浏览器中打开,发现有横向滚动条。为什么呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html lang="en">
<head>
<style>
body {
width: 100%;
}
</style>
</head>
<body>
This is body
</body>
</html>
Read more »