diff --git a/docs/vite_vanilla_ts/_category_.json b/docs/vite_vanilla_ts/_category_.json
new file mode 100644
index 0000000..2a6ab1e
--- /dev/null
+++ b/docs/vite_vanilla_ts/_category_.json
@@ -0,0 +1,7 @@
+{
+ "label": "vanilla ts工程",
+ "position": 12,
+ "link": {
+ "type": "generated-index"
+ }
+}
\ No newline at end of file
diff --git a/docs/vite_vanilla_ts/result.png b/docs/vite_vanilla_ts/result.png
new file mode 100644
index 0000000..050ad7b
Binary files /dev/null and b/docs/vite_vanilla_ts/result.png differ
diff --git a/docs/vite_vanilla_ts/vite_vanilla_ts.md b/docs/vite_vanilla_ts/vite_vanilla_ts.md
new file mode 100644
index 0000000..e98b35e
--- /dev/null
+++ b/docs/vite_vanilla_ts/vite_vanilla_ts.md
@@ -0,0 +1,200 @@
+---
+sidebar_position: 1
+---
+# 如何使用html+ts编写前端todo list
+
+## 先决条件
+1. 已创建vanilla ts工程
+
+>**提示**
+若未安装vanilla ts工程,可以参考[vite的入门](http://localhost:3000/full-stack-tutorial/docs/vite)文档
+
+## 项目初始化
+打开vanilla ts工程
+
+## 编写HTML结构
+在`index.html`中,通过以下代码,编写todo list的样式和基本结构
+```
+
+
+
+
+
+
+ Document
+
+
+
+
+
+
+
+
+
+
+
+ 吃饭
+ 完成
+ 删除
+
+
+
+ 睡觉
+ 完成
+ 删除
+
+
+
+ 打豆豆
+ 完成
+ 删除
+
+
+
+
还有1 个未完成
+
+ 筛选:
+ 全部
+ 未完成
+ 已完成
+ 清空
+
+
+
+
+
+
+
+
+
+```
+## 编写TypeScript逻辑
+在`main.ts`中,编写以下代码,实现todo list的功能
+```
+//定义接口TodoItem
+interface TodoItem {
+ name: string;
+ completed: boolean;
+}
+
+//初始化数组
+let list: TodoItem[] = [
+ { name: '吃饭', completed: false },
+ { name: '睡觉', completed: true },
+ { name: '打豆豆', completed: true },
+];
+
+//监听在输入框中按下回车键的事件
+document.querySelector('.input-todo')!.addEventListener('keyup', function (e: Event) {
+ const event = e as KeyboardEvent;
+ const target = event.target as HTMLInputElement;
+ if (!target.value?.trim()) {
+ return;
+ }
+ if (event.key === 'Enter') {
+ const name = target.value;
+ const item: TodoItem = { name, completed: false };
+ list.push(item);
+ render(list);
+ target.value = '';
+ }
+});
+
+//实现筛选功能
+document.querySelectorAll('.filter-btn').forEach((el) => {
+ el.addEventListener('click', filterCompletedStatus);
+});
+
+function filterCompletedStatus(e: Event) {
+ const target = e.target as HTMLElement;
+ const completed = target.dataset.complete;
+
+ if (completed === 'all') {
+ render(list);
+ return;
+ }
+
+ const newList = list.filter((item) => item.completed === (completed === 'true'));
+ renderTodoList(newList);
+}
+
+document.querySelector('.btn-clear')!.addEventListener('click', () => {
+ list = [];
+ render(list);
+});
+
+//切换completed的状态
+function onClickCompleteBtn(index: number) {
+ list[index].completed = !list[index].completed;
+ render(list);
+}
+
+//渲染数组
+function render(list: TodoItem[]) {
+ UpdateActiveNum();
+ renderTodoList(list);
+}
+
+//统计筛选中未完成功能数量
+function UpdateActiveNum() {
+ const completedNum = list.filter((item) => !item.completed).length;
+ document.querySelector('.active-num')!.innerHTML = completedNum.toString();
+}
+
+//实现删除功能
+function deleteItem(index: number) {
+ list.splice(index, 1);
+ render(list);
+}
+
+//渲染html
+function renderTodoList(list: TodoItem[]) {
+ let html = '';
+ list.forEach((item, index) => {
+ const itemClass = item.completed ? 'item-complete todo-item' : 'todo-item';
+ const spanClass = item.completed ? 'icon-complete icon-complete-active' : 'icon-complete';
+ html += `
+
+ ${item.name}
+ 完成
+ 删除
+ `;
+ });
+ document.querySelector('.todo-list')!.innerHTML = html;
+}
+```
+## 运行项目
+按下快捷键`Ctrl + ~`,打开终端,输入以下命令,运行项目
+```
+npm run dev
+```
+
\ No newline at end of file