建议搭配视频讲解食用~
https://www.bilibili.com/video/BV1Jt4y1k7dS
传统写法
绑定事件处理函数 – 数据
-
增加项 – 列表数据 -> 增加一项
{ id timestamp, content string, completed: false }
每一项的视图 -> 列表
-
删除项 – 列表数据 -> id ->
removeItem
将对应项的视图 -> 列表 -> 删除 -
改变完成状态 – 列表数据 -> id ->
change completed
将对应项的完成状态 -> 是否完成toggle
面向对象、类的继承、横向切割程序 – 设计方案
程序进行分类 外层:调用浏览器的事件 -> 调用方法 -> 事件处理函数的绑定 操作数据:addTodo
、removeTodo
、toggleComplete
操作DOM:addItem
、removeItem
、changeCompleted
管理模板:todoView
-> 接收参数,生成视觉模板
1目录结构
初始化npm项目,并初始化ts配置。
npm init
tsc --init
可使用vite
启动项目。
npm install vite -D
vite
![[typescript]原生ts实现todoList [typescript]原生ts实现todoList](https://www.bmabk.com/wp-content/uploads/2022/05/post-loading.gif)
2index.html
文件
主页入口。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="app">
<div class="todo-input">
<input type="text" placeholder="请输入代办事项">
<button>增加</button>
</div>
<div class="todo-list"></div>
</div>
<script type="module" src="./src/app.ts"></script>
</body>
</html>
3js/typings.ts
文件
定义一个item的数据结构。
export interface ITodoData {
id: number;
content: string;
completed: boolean;
}
4js/utils.ts
文件
一些工具方法。
// 找到指定className的父节点
export function findParentNode (target: HTMLElement, className: string): HTMLElement {
while (target = target.parentNode as HTMLElement) {
if (target.className === className) {
return target;
}
}
}
// 创建一个todoList的Item
export function createItem (tagName: string, className: string, todoItem: string): HTMLElement {
const oItem: HTMLElement = document.createElement(tagName);
oItem.className = className;
oItem.innerHTML = todoItem;
return oItem;
}
5js/TodoTemplate.ts
文件
传入一个ITodoData对象,生成一个todoItem
的template
。
import { ITodoData } from "./typings";
class TodoTemplate {
// 传入一个ITodoData,生成view的渲染模板
protected todoView ({ id, content, completed }: ITodoData): string {
return `
<input type="checkbox" ${ completed ? 'checked' : '' } color: #e06c75;line-height: 26px;">${ id }" />
<span style="text-decoration: ${ completed ? 'line-through' : 'none' }">${ content }</span>
<button color: #e06c75;line-height: 26px;">${ id }">删除</button>
`;
}
}
export default TodoTemplate;
6js/TodoDom.ts
文件
封装操作
import TodoTemplate from "./TodoTemplate";
import { ITodoData } from "./typings";
import { createItem, findParentNode } from "./utils";
class TodoDom extends TodoTemplate {
private todoWrapper: HTMLElement;
constructor(todoWrapper: HTMLElement) {
super();
this.todoWrapper = todoWrapper;
}
// 初始化todoList列表
protected initList (todoData: ITodoData[]) {
if (todoData.length) {
const oFrag: DocumentFragment = document.createDocumentFragment();
todoData.map((todo: ITodoData) => {
const oItem: HTMLElement = createItem('div', 'todo-item', this.todoView(todo));
oFrag.appendChild(oItem);
});
this.todoWrapper.appendChild(oFrag);
}
}
// 添加一个todo的item
protected addItem (todo: ITodoData) {
const oItem: HTMLElement = createItem('div', 'todo-item', this.todoView(todo));
this.todoWrapper.appendChild(oItem);
}
// 删除item
protected removeItem (target: HTMLElement) {
const oParentNode: HTMLElement = findParentNode(target, 'todo-item');
oParentNode.remove();
}
// 切换是否完成状态
protected changeCompleted (target: HTMLElement, completed: boolean) {
const oParentNode: HTMLElement = findParentNode(target, 'todo-item');
const oContent: HTMLElement = oParentNode.getElementsByTagName('span')[0];
oContent.style.textDecoration = completed ? 'line-through' : 'none';
}
}
export default TodoDom;
7js/TodoEvent.ts
文件
在操作Dom的类上继承,实现事件的处理
import TodoDom from "./TodoDom";
import { ITodoData } from "./typings";
class TodoEvent extends TodoDom {
private todoData: ITodoData[];
constructor (todoData: ITodoData[], todoWrapper: HTMLElement) {
super(todoWrapper);
this.todoData = todoData;
this.init();
}
// 添加数据
public addTodo (todo: ITodoData): undefined | number {
const _todo: null | ITodoData = this.todoData.find((item: ITodoData) => item.content === todo.content);
if (!_todo) {
this.todoData.push(todo);
this.addItem(todo);
return;
}
return 1001;
}
// 初始化数据
private init () {
this.initList(this.todoData);
}
// 删除todo
public removeTodo (target: HTMLElement, id: number): void {
this.todoData = this.todoData.filter((todo: ITodoData) => todo.id !== id);
this.removeItem(target);
}
// 点击切换完成状态
public toggleComplete (target: HTMLElement, id: number): void {
this.todoData = this.todoData.map((todo: ITodoData) => {
if (todo.id === id) {
todo.completed = !todo.completed;
this.changeCompleted(target, todo.completed);
}
return todo;
})
}
}
export default TodoEvent;
8最后效果
![[typescript]原生ts实现todoList [typescript]原生ts实现todoList](https://www.bmabk.com/wp-content/uploads/2022/05/post-loading.gif)
原文始发于微信公众号(豆子前端):[typescript]原生ts实现todoList
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/56659.html