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;
}

创建工程

npm init vite@latest

后续选择:react + ts 添加必要文件,工程结构如下:

定义全局数据类型

src/vite-env.d.ts

/// <reference types="vite/client" />

/* 代办事项数据结构 */
interface TodoItem {
    name: string,
    done: boolean
}

/* 通用DOM事件处理器 */
type EventHandler = (e?: SyntheticEvent) => void

/* 处理函数定义:点击提交按钮 */
type UserInputHandler = (userInput: string, e?: SyntheticEvent) => void

/* 处理函数定义:点击列表条目 */
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
}

实现步骤

在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具体实现: 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>
    )
}

用户输入框组件实现: 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>
    )
}

列表展示组件实现: 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

到此这篇关于Vite+React+TypeScript手撸TodoList的项目实践的文章就介绍到这了,更多相关Vite React TypeScript TodoList内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • React+Redux实现简单的待办事项列表ToDoList

    使用Redux做了一个简单的ToDoList待办事项列表 这个例子也是源于Redux作者Dan Abramov的视频demo 还要特别说明一下 我还没有使用react-redux库进行解耦(可能以后加) 也没有拆分成多个文件等等优化 为了单纯的练习redux 适合初步学习redux的同学 本人学疏才浅,发现可以优化的地方或者问题还请大家指正,谢谢 功能样式 样子就是这样的 在输入框输入待办事项 功能很简单 鼠标点击Add或者键盘按下Enter输出 ShowAll显示全部待办事项 ShowActi

  • React-redux实现小案例(todolist)的过程

    使用React-redux实现,待办事项todolist案例. 注:以下列出主要页面代码,为说明React-redux实现的过程,所以并没有将案例的完整代码展示! 一.全局安装:rudux.react-redux npm install redux --save npm install react-redux 二.主要代码: 1.项目的入口文件index.js import React from 'react'; import ReactDOM from 'react-dom'; import

  • react用Redux中央仓库实现一个todolist

    本文实例为大家分享了react用Redux中央仓库实现一个todolist的具体代码,供大家参考,具体内容如下 Redux简单介绍 Redux是一个用来管理管理数据状态和UI状态的JavaScript应用工具.随着JavaScript单页应用(SPA)开发日趋复杂,JavaScript需要管理比任何时候都要多的state(状态),Redux就是降低管理难度的.(Redux支持React,Angular.jQuery甚至纯JavaScript) Redux Dev Tools插件 Redux调试工

  • React实现todolist功能

    一.index.js ReactDOM.render( <React.StrictMode> <TodoList /> </React.StrictMode>, document.getElementById('root') ); 二.TodoList 1.constructor constructor(props) { super(props); this.state = { inputValue: '', list: [] } } 2.render render()

  • react+redux的升级版todoList的实现

    又是很久不写博客了,最近在用蚂蚁金服的ant-design-pro写毕设,写着写着写不下去了,很多东西都不理解,不得不说大神写出来的东西都是需要花学习成本的,或者底子好,对于React新手来说就有点难了.所以就老老实实的认真看了下Redux到底如何使用,在这里推荐一下自己最近在看的书,写的算是比较详细的:<深入React技术栈>.废话不多说,今天就分享下自己如何使用redux来实现一个todoList的,希望对想要用redux的你会有所帮助. (为什么叫升级版呢?因为之前写过一个没有用redu

  • 用React实现一个完整的TodoList的示例代码

    前言:算起来已经有一个多月没有写博客了,近来懈怠了不少,也不知道要写些什么,最近学了一段时间的React,一直都在看些理论性的知识,总觉得应该写个什么来练练手,所以还是拿个简单的todoList来举个例子吧! 一. 首先根据效果图讲一下要实现的功能吧 todoList最终效果图 (1)可以添加任务: (2)已完成任务以及未完成任务的颜色区分开: (3)进行添加任务,修改任务状态,以及删除任务时,下面的任务完成数目和任务总数要进行变化: 以上就是要实现的功能. 二. 接下来该如何设计呢? (1)任

  • react实现todolist的增删改查详解

    目录 以todolist为例 目录如下 app.js Input.js List.js Item.js Total.js Mask.js(弹窗) bus.js App.css 总结 以todolist为例 目录如下 app.js import React, { PureComponent } from 'react' import Input from './components/Input' import List from './components/List' import Total f

  • 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; l

  • vite + react +typescript 环境搭建小白入门教程

    目录 前言 1. 使用 vite 创建 react 项目 1. npm / yarn 命令初始化 2. 输入项目名称 3. 选择框架 4. 选择 Js / Ts 5. 项目创建完成 6. 启动项目 2. 规范项目目录 3. 使用 react-router-dom 路由 1. 使用 npm / yarn 命令下载 2. 更改 react-router-dom 版本 3. 修改App.tsx文件 4. 配置 alias 别名 5. 配置 Ant Design 样式库 6. 配置axios与顶部加载进

  • React+TypeScript进行项目构建案例讲解

        react项目构建可以很简单,但是如果是结合typescript,其实也不是很麻烦,官网也有很明确的说明.有两种办法:     1.直接构建带有typescript的react项目,我们需要增加额外的参数,模版不能使用默认的cra-template.而是使用cra-template-typescript. npx create-react-app tsreactdemo --template typescript           创建完成的成功提示与原来没有太大的区别,直接进入项目路

  • Vite+React搭建开发构建环境实践记录

    目录 前言 使用 create-vite 脚手架生成基础模板 eslint prettier react-router antd 别名 Less 与 CSS Module 总结 前言 使用 Vite 已经有两年了,期间使用它开发过单页面应用,也开发过浏览器扩展插件,对比日常工作中用到的 webpack 构建速度大幅提升,开发体验也好很多.虽然相比于 webpack 来说简单了很多,但是仍然有一些配置需要记录一下,以便之后可以快速搭建一个本地开发构建的环境. 使用 create-vite 脚手架生

  • React+TypeScript+webpack4多入口配置详解

    资源 React-16.8.* react-router-dom-4.3.* TypeScript-3.5.* webpack-4.* eslint-5.16.* 项目目录 ├── dist # 打包结果目录 │ ├── demo1 //类别demo1的打包结果 │ │ ├── demo1.himl │ │ ├── demo1.js │ │ └── demo1.css │ └── demo2 ... //类别demo2的打包结果 ├── src # 业务资源文件目录 │ ├── category

  • 手撸一个 spring-boot-starter的全过程

    我们使用 Spring Boot,基本上都是沉醉在它 Stater 的方便之中.Starter 为我们带来了众多的自动化配置,有了这些自动化配置,我们可以不费吹灰之力就能搭建一个生产级开发环境,有的小伙伴会觉得这个 Starter 好神奇呀!其实 Starter 也都是 Spring + SpringMVC 中的基础知识点实现的,接下来带大家自己来撸一个 Starter ,慢慢揭开 Starter 的神秘面纱! 核心知识 其实 Starter 的核心就是条件注解 @Conditional ,当

  • vite+vue3.0+ts+element-plus快速搭建项目的实现

    vite 出了 2.x 版本,抱着学一学的心态决定出个简单的项目,结合 element-plus,以及将会成为每位前端必会的 typescript,实现了如下内容. vite是一个由原生 ESM 驱动的 Web 开发构建工具.在开发环境下基于浏览器原生 ES imports 开发,在生产环境下基于 Rollup 打包. vite 作用 快速的冷启动:不需要等待打包操作: 即时的热模块更新:替换性能和模块数量的解耦让更新飞起: 真正的按需编译:不再等待整个应用编译完成,这是一个巨大的改变. 使用的

  • 半小时实现Java手撸网络爬虫框架(附完整源码)

    最近在做一个搜索相关的项目,需要爬取网络上的一些链接存储到索引库中,虽然有很多开源的强大的爬虫框架,但本着学习的态度,自己写了一个简单的网络爬虫,以便了解其中的原理.今天,就为小伙伴们分享下这个简单的爬虫程序!! 首先介绍每个类的功能: DownloadPage.java的功能是下载此超链接的页面源代码. FunctionUtils.java 的功能是提供不同的静态方法,包括:页面链接正则表达式匹配,获取URL链接的元素,判断是否创建文件,获取页面的Url并将其转换为规范的Url,截取网页网页源

  • vite创建一个标准vue3+ts+pinia项目

    目录 [01]使用的 Yarn创建项目: [02]在项目中使用pinia [03]添加vue-router [04] 安装按需自动导入插件 [05] 添加element-plus组件库 [06]添加sass [07] 安裝prettier 和 eslint 1.安装依赖项 使用vite创建一个标准vue3+ts+pinia项目的实现示例 [01]使用的 Yarn创建项目: 1.执行命令 yarn create vite my-vue-app --template vue-ts 3.cd my-v

  • 手撸一个Spring Boot Starter并上传到Maven中央仓库

    目录 打包上传到中央仓库 第一步 在issues.sonatype.org注册一个账号 第二步 在issues.sonatype.org提交Issue 第三步 配置Maven Setting.xml 第四步 配置项目的pom.xml 第五步 安装和配置GPG 第六步 项目打包上传 第七步 处理验证 问题 我1.0.1版本发布错了,有办法修改或者删除吗? 先手撸一个Spring Boot Starter 准备搞个项目,包含以下几个功能后边还会加新功能. 配置项加密(已实现) 服务调用链 数据脱敏

随机推荐