前言
我是歌谣 最好的种树是十年前 其次是现在 今天继续给大家带来的是原始typescript的讲解
环境配置
npm init -y
yarn add vite -D
修改page.json配置端口
代码语言:javascript复制{
"name": "demo1",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "vite --port 3002"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"vite": "^4.4.9"
}
}
目录结构
index.html
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ts</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>
app.ts
代码语言:javascript复制import { ITodoData } from "./typings";
import TodoEvent from "./TodoEvent";
; ((doc) => {
const oInput: HTMLInputElement = document.querySelector('input') as HTMLInputElement
const oAddBtn: HTMLElement = document.querySelector('button') as HTMLElement
const oTodoList: HTMLElement = document.querySelector('.todo-list') as HTMLElement
const todoData: ITodoData[] = [
{
id: 1,
content: 'geyao',
completed: false
},
{
id: 2,
content: 'fangfang',
completed: false
},
{
id: 3,
content: 'kang',
completed: false
}
]
const init = (): void => {
bindEvent()
}
function bindEvent(): void {
oAddBtn.addEventListener("click", handleAddBtnClick, false)
oTodoList.addEventListener("click", handleListClick, false)
}
function handleAddBtnClick(): void {
const val:string=oInput.value.trim()
console.log(val,"val is")
if(val.length){
const ret= todoEvent.addTodo(<ITodoData>{
id: 4,
content: val,
completed: false
})
if(ret&&ret===1001){
alert("列表已经存在")
return
}
oInput.value=''
}
}
function handleListClick(e: MouseEvent): void {
const tar = e.target as HTMLElement
const tagName = tar.tagName.toLowerCase()
if (tagName === 'input' || tagName === 'button') {
const id=parseInt(tar.dataset.id as string)
switch (tagName) {
case 'input':
todoEvent.toggleComplete(tar,id)
break;
case 'button':
todoEvent.removeTodo(tar,id)
break;
default:
break;
}
}
}
const todoEvent: TodoEvent = new TodoEvent(todoData,oTodoList)
init()
})(document)
TodoDom.ts
代码语言:javascript复制import TodoTemplate from "./TodoTemplate";
import { ITodoData } from "./typings";
import { createItem, findParentNode } from "./utils";
class TodoDom extends TodoTemplate{
private todoWarpper:HTMLElement;
constructor(todoWarpper:HTMLElement){
super()
this.todoWarpper=todoWarpper
}
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))
// const oItem:HTMLElement=document.createElement("div")
// oItem.className='todo-item'
// oItem.innerHTML=this.todoView(todo)
oFrag.appendChild(oItem)
})
this.todoWarpper.appendChild(oFrag)
}
}
protected addItem(todo:ITodoData){
const oItem:HTMLElement= createItem("div","todo-item",this.todoView(todo))
// const oItem:HTMLElement=document.createElement('div');
// oItem.className='todo-item'
// oItem.innerHTML=this.todoView(todo)
this.todoWarpper.appendChild(oItem)
}
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
todoEvent.ts
代码语言:javascript复制import TodoDom from "./TodoDom";
import { ITodoData } from "./typings";
class TodoEvent extends TodoDom{
private todoData: ITodoData[]
constructor(todoData: ITodoData[],todoWarpper:HTMLElement) {
super(todoWarpper)
this.todoData = todoData
this.init()
}
public addTodo(todo: ITodoData): undefined | number {
const _todo: null | ITodoData | undefined = this.todoData.find((item: ITodoData) => item.content===todo.content)
console.log(_todo,"_todo is")
if (!_todo) {
this.todoData.push(todo)
this.addItem(todo)
return
}
return 1001
}
protected init(){
this.initList(this.todoData)
}
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
todoTemplate.ts
代码语言:javascript复制import { ITodoData } from "./typings";
class TodoTemplate{
protected todoView({id,content,completed}:ITodoData):string{
return `
<input type="checkbox" ${completed}?'checked':'' data-id="${id}"/>
<span style="text-decoration":${completed}?'line-through':'none'>${content}</span>
<button data-id='${id}'>删除</button>
`
}
}
export default TodoTemplate
typing.ts
代码语言:javascript复制export interface ITodoData{
id:number,
content:string,
completed:boolean
}
utils.ts
代码语言:javascript复制import { callbackify } from "util"
export function findParentNode(target:HTMLElement,className:string):any{
while(target=target.parentNode as HTMLElement){
if(target.className===className){
return target
}
}
}
export function createItem(tagName:string,className:string,todoItem:string):HTMLElement{
const oItem:HTMLElement=document.createElement(tagName)
oItem.className=className
oItem.innerHTML=todoItem
return oItem
}
运行结果