Vite+React+TypeScript手撸TodoList的项目实践
短信预约 -IT技能 免费直播动态提醒
布局与样式
一个TodoList长什么样子相信无需多言:
上样式: class="lazy" data-src/TodoList.css
.td-wrapper {
width: 700px;
margin: 0 auto;
}
.dp-wrapper {
width: 100%;
height: 40px;
display: flex;
margin-top: 10px;
}
.dp-wrapper input {
flex: 4;
height: 36px;
line-height: 36px;
text-indent: 10px;
font-size: 1rem;
}
.dp-wrapper button {
flex: 1;
height: 100%;
margin-left: 2px;
font-size: 1rem;
}
.dl-wrapper {
border: 1px solid gray;
margin-top: 5px;
}
.dl-wrapper li {
height: 40px;
line-height: 40px;
border-bottom: 1px solid gray;
}
.dl-wrapper li.done {
text-decoration: line-through;
}
.dl-wrapper li:last-child {
border-bottom: none;
}
创建工程
npm init vite@latest
后续选择:react + ts 添加必要文件,工程结构如下:
定义全局数据类型
class="lazy" data-src/vite-env.d.ts
/// <reference types="vite/client" />
interface TodoItem {
name: string,
done: boolean
}
type EventHandler = (e?: SyntheticEvent) => void
type UserInputHandler = (userInput: string, e?: SyntheticEvent) => void
type ImteClickHandler = (index: number, e?: SyntheticEvent) => void
type ItemClassNameGetter = (index: number) => string
interface DataPickerProps {
onUserInput: UserInputHandler
}
interface DataListerProps {
list: TodoItem[],
onItemClick: ImteClickHandler,
getClassName: ItemClassNameGetter
}
实现步骤
在App.tsx中加载TodoList:
import { useState } from 'react'
import './App.css'
import TodoList from './TodoList'
function App() {
return (
<div className="App">
<TodoList></TodoList>
</div>
)
}
export default App
父组件TodoList具体实现: class="lazy" data-src/TodoList.tsx
import React, { useState } from 'react'
import DataLister from './DataLister'
import DataPicker from './DataPicker'
import "./TodoList.css"
export default function TodoList() {
const [todoList, setTodoList] = useState([
{ name: "抽中华", done: false },
{ name: "喝剑南春", done: false },
{ name: "烫杀马特", done: true },
])
const addTodoItem: UserInputHandler = (userInput: string) => {
setTodoList([
{ name: userInput, done: false },
...todoList
])
}
const switchTodoitemState: ImteClickHandler = (index: number) => {
setTodoList(
todoList.map(
(item, i) => (
i !== index ? item : { ...item, done: !item.done }
)
)
)
}
const getTodoitemClassName: ItemClassNameGetter = (index: number) => {
return todoList[index].done ? "done" : ""
}
return (
<div className="td-wrapper">
<h3>TodoList</h3>
<DataPicker onUserInput={addTodoItem} />
<DataLister
list={todoList}
onItemClick={switchTodoitemState}
getClassName={getTodoitemClassName}
/>
</div>
)
}
用户输入框组件实现: class="lazy" data-src/DataPicker.tsx
import React, { SyntheticEvent, useState } from 'react'
export default function DataPicker({ onUserInput }: DataPickerProps) {
const [userInput, setUserInput] = useState("骚年请输入你的闷响...")
const onUserInputChange: EventHandler = (e: SyntheticEvent) => {
setUserInput((e.target as HTMLInputElement).value)
}
const onSubmit: EventHandler = (e: SyntheticEvent) => {
onUserInput(userInput)
// 清空用户输入
setUserInput("")
}
return (
<div className='dp-wrapper'>
<input type="text" value={userInput} onChange={onUserInputChange} />
<button onClick={onSubmit}>提交</button>
</div>
)
}
列表展示组件实现: class="lazy" data-src/DataLister.tsx
export default function DataLister({ list, onItemClick, getClassName }: DataListerProps) {
return (
<div className='dl-wrapper'>
<ul>{
list.map(
(item: TodoItem, index: number) => (
<li
key={index + item.name}
className={getClassName(index)}
onClick={() => {
onItemClick(index)
}}>
{item.name}
</li>
)
)
}</ul>
</div>
)
}
源码地址
git clone https://gitee.com/steveouyang/todolist-vite-react-ts.git
到此这篇关于Vite+React+TypeScript手撸TodoList的项目实践的文章就介绍到这了,更多相关Vite React TypeScript TodoList内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341