Vite+React+TypeScript手擼TodoList的項目實踐
布局與樣式
一個TodoList長什么樣子相信無需多言:
上樣式: 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; }
創(chuàng)建工程
npm init vite@latest
后續(xù)選擇:react + ts 添加必要文件,工程結(jié)構(gòu)如下:
定義全局數(shù)據(jù)類型
src/vite-env.d.ts
/// <reference types="vite/client" /> /* 代辦事項數(shù)據(jù)結(jié)構(gòu) */ interface TodoItem { name: string, done: boolean } /* 通用DOM事件處理器 */ type EventHandler = (e?: SyntheticEvent) => void /* 處理函數(shù)定義:點擊提交按鈕 */ type UserInputHandler = (userInput: string, e?: SyntheticEvent) => void /* 處理函數(shù)定義:點擊列表條目 */ type ImteClickHandler = (index: number, e?: SyntheticEvent) => void /* 獲取指定Item的樣式名 */ type ItemClassNameGetter = (index: number) => string /* 定義DataPicker組件的Props */ interface DataPickerProps { onUserInput: UserInputHandler } /* 定義DataLister組件的Props */ interface DataListerProps { list: TodoItem[], onItemClick: ImteClickHandler, getClassName: ItemClassNameGetter }
實現(xiàn)步驟
在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具體實現(xiàn): 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 ]) } /* 切換代辦事項完成狀態(tài) */ const switchTodoitemState: ImteClickHandler = (index: number) => { setTodoList( todoList.map( (item, i) => ( i !== index ? item : { ...item, done: !item.done } ) ) ) } /* 根據(jù)條目完成與否返回不同的樣式名 */ 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> ) }
用戶輸入框組件實現(xiàn): src/DataPicker.tsx
import React, { SyntheticEvent, useState } from 'react' export default function DataPicker({ onUserInput }: DataPickerProps) { /* 定義響應式數(shù)據(jù):用戶輸入的內(nèi)容 */ const [userInput, setUserInput] = useState("騷年請輸入你的悶響...") /* 受控組件的雙向數(shù)據(jù)綁定 */ 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> ) }
列表展示組件實現(xiàn): 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={() => { /* 告訴父組件第幾個item被點擊了 具體如何處置由父元素自行決定 */ onItemClick(index) }}> {item.name} </li> ) ) }</ul> </div> ) }
源碼地址
git clone https://gitee.com/steveouyang/todolist-vite-react-ts.git
到此這篇關(guān)于Vite+React+TypeScript手擼TodoList的項目實踐的文章就介紹到這了,更多相關(guān)Vite React TypeScript TodoList內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
React onClick/onChange傳參(bind綁定)問題
這篇文章主要介紹了React onClick/onChange傳參(bind綁定)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-02-02React中memo useCallback useMemo方法作用及使用場景
這篇文章主要為大家介紹了React中三個hooks方法memo useCallback useMemo的作用及使用場景示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助2023-03-03React+Antd+Redux實現(xiàn)待辦事件的方法
這篇文章主要介紹了React+Antd+Redux實現(xiàn)待辦事件的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-03-03react中使用echarts,并實現(xiàn)tooltip循環(huán)輪播方式
這篇文章主要介紹了react中使用echarts,并實現(xiàn)tooltip循環(huán)輪播方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01React 進入頁面后自動 focus 到某個輸入框的解決方案
React.js 當中提供了 ref 屬性來幫助我們獲取已經(jīng)掛載的元素的 DOM 節(jié)點,你可以給某個 JSX 元素加上 ref屬性,這篇文章主要介紹了React 進入頁面以后自動 focus 到某個輸入框,需要的朋友可以參考下2024-02-02詳解Webpack+Babel+React開發(fā)環(huán)境的搭建的方法步驟
本篇文章主要介紹了詳解Webpack+Babel+React開發(fā)環(huán)境的搭建的方法步驟,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-01-01