类型即正义:TypeScript 从入门到实践(序章)

做者:一只图雀
仓库:GithubGitee
图雀社区主站(首发):图雀社区
博客:掘金知乎慕课
公众号:图雀社区
联系我:关注公众号后能够加图雀酱微信哦
原创不易,❤️点赞+评论+收藏 ❤️三连,鼓励做者写出更好的教程javascript

准备代码


由于须要尽量全且精炼的讲解 TypeScript 语法知识,因此咱们须要一个恰到好处的实战项目,这一小节主要是用于讲解咱们准备初始 TypeScript 版本的 React 项目代码的过程,在下一个小节中咱们将会结合 React 项目代码,真正开始 TypeScript 语法的讲解。
css

本文所涉及的源代码都放在了 Github  或者 Gitee 上,若是您以为咱们写得还不错,但愿您能给❤️这篇文章点赞GithubGitee 仓库加星❤️哦~前端

此教程属于 React 前端工程师学习路线的一部分,欢迎来 Star 一波,鼓励咱们继续创做出更好的教程,持续更新中~java

前提条件

  1. 确保你已经安装了 Node.js,能够访问官网安装:官网地址
  2. 确保你已经了解基本的 React 开发知识,图雀社区有一篇很好的 React 入门教程,你能够经过学习它很快的上手 React。
  3. 确保你有必定的命令行使用基础,包括使用 Npm (Node.js 包管理工具)来安装包。

初始化应用


初始一个 React 应用的最佳方式那么必定是 React 官方维护的 Create React App 脚手架了,咱们打开终端,运行以下命令来初始化一个 TypeScript 版本的 React 应用:
node

$ npx create-react-app typescript-tea --template typescript
复制代码


运行如上命令,命令行里面应该会有一系列输出,等待几分钟,就会提示已经初始化完成,并提供了对于的命令来帮助你开启项目,咱们根据提示输入以下命令来开启项目:
react

$ cd typescript-tea
$ npm start
复制代码


运行如上命令以后,会自动开启 Webpack 开发服务器,并打开浏览器窗户,访问 http://localhost:3000/ 来展现你的应用初始界面:

git



若是看到这个界面,恭喜你🥳!成功建立一个 TypeScript 版本的 React 应用!

提示 在下文中,为了简化语言,咱们统一称 TypeScript 为 TS。github

引入 antd 组件库


实战驱动的技术学习能带给咱们成就感,便捷好用的包能够加快咱们的开发效率,好看的界面能够提升咱们的审美能力,缓解学习疲劳。在这篇教程的讲解过程当中,咱们将经过 Ant Design 对应的 React 组件库 antd 来辅助咱们项目的编写,使得咱们能够专一于讲解 TS 的核心知识,而不被繁杂的界面语言所干扰,还能作出对应相应完成的目标功能。
typescript

提示 Ant Design 是蚂蚁金服孵化的一套企业级产品设计体系,提供了完备的 TS 类型定义,使得咱们能够很方便的在 TS 项目中使用,在最近发布了 4.0 版本,致力于创造高效愉悦的工做体验。 除此以外 Ant Design 的周边生态也很丰富:npm

  • 包括新一代数据可视化解决方案:AntV
  • 一个基于 Preact / React / React Native 的 UI 组件库:Ant Design Mobile
  • 开箱即用的中台前端/设计解决方案:Ant Design Pro
  • 插画设计:海兔
  • 一款为设计者提高工做效率的 Sketch 工具集 : Kitchen

后面图雀社区计划围绕 Ant Design 生态撰写一系列教程,帮助你们提升设计、开发效率,敬请期待!✌️

安装依赖


好了,大体介绍了 antd 组件库及 Ant Design 周边以后,咱们立刻来写代码引入 antd,打开命令行,在其中输入以下命令:

$ npm install antd
复制代码


运行上面的命令安装完依赖以后就能够在项目中使用了,可是为了更好的定制样式和按需引用以减少打包以后的包体积,咱们还须要作一点定制化的操做,打开命令行,依次安装以下依赖:

$ npm install react-app-rewired customize-cra babel-plugin-import less less-loader
复制代码


注意到上面咱们安装了不少包,咱们来依次解释一下上面各类包的意思:

  • react-app-rewired:用来定制化 Create React App (CRA)脚手架的一些配置,好比 Webpack、Babel 等,由于 CRA 它是一个封闭的黑盒,不容许开发者直接定制,但有时候咱们须要对配置作一些修改,好比这里须要配置 antd 的按需引用。
  • customize-cra:是 CRA 在发布 2.0 以后出来的一个辅助 react-app-rewired 更方便定制 CRA 的 Webpack 配置的一个库,它提供了一些开箱即用的 API。
  • babel-plugin-import:是配置可供开发者按需引用 antd 组件的一个 Babel 插件
  • less 和 less-loader:是咱们用于定制化 antd 的主题须要的 Webpack loader,由于 antd 使用 less 做为样式化语言。


最后咱们安装一个在 Ant Design 4.0 拆分出去的 icons 包,能够用来按需引用 icons,进一步减小最后的打包体积,继续在命令行运行以下命令:

$ npm install @ant-design/icons
复制代码


大功告成!如今咱们全部的依赖以及安装完成。接下来就须要改写一下 CRA 以前经过 react-scripts  跑开发构建的流程,用咱们安装的 react-app-rewired  脚原本替换它,当安装完了因此依赖,以及用react-app-rewired   替换 react-scripts  以后,咱们的 package.json  文件应该是下面的样子:

// ...
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@ant-design/icons": "^4.0.2",
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.3.2",
    "@testing-library/user-event": "^7.1.2",
    "@types/jest": "^24.0.0",
    "@types/node": "^12.0.0",
    "@types/react": "^16.9.0",
    "@types/react-dom": "^16.9.0",
    "antd": "^4.0.0",
    "babel-plugin-import": "^1.13.0",
    "customize-cra": "^0.9.1",
    "less": "^3.11.1",
    "less-loader": "^5.0.0",
    "react": "^16.13.0",
    "react-app-rewired": "^2.1.5",
    "react-dom": "^16.13.0",
    "react-scripts": "3.4.0",
    "typescript": "~3.7.2"
  },
  "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    "eject": "react-scripts eject"
  },
  // ...
复制代码

修改配置


安装完依赖以后,咱们要确保对应改写 CRA 流程的配置生效,咱们须要根据 react-app-rewired 的文档说明在根目录下创建 config-overrides.js 文件,并在其中编写以下的内容:

const { override, fixBabelImports, addLessLoader } = require("customize-cra");
const darkThemeVars = require("antd/dist/dark-theme");

module.exports = override(
  fixBabelImports("import", {
    libraryName: "antd",
    libraryDirectory: "es",
    style: true
  }),
  addLessLoader({
    javascriptEnabled: true,
    modifyVars: {
      hack: `true;@import "${require.resolve( "antd/lib/style/color/colorPalette.less" )}";`,
      ...darkThemeVars,
      "@primary-color": "#02b875"
    }
  })
);
复制代码


能够看到,上面的代码主要是导出一个用于修改 Webpack 配置的对象,使用 override API,接收两个修改配置的函数调用,fixBabelImports 用于配置 antd 的按需引用,addLessLoader 用于配置 antd 的主题,这里咱们使用了 Ant Design 4.0 新带来的 Dark Mode(暗色模式),而后配置了主题色为图雀社区的主题色:#02b875 ,表明但愿的绿色。😆

自此,咱们就引入了 antd 组件库,并进行了按需配置使用以及配置主题色和使用了 Ant Design 最新的暗色主题 -- Dark Mode。

编写初始代码

准备逻辑部分


接下来,咱们将使用 antd 帮助咱们快速的编写一下咱们即将实现的待办事项的界面,打开 src/App.tsx ,对其中的代码作出对应的修改以下:

import React, { useState, useRef } from "react";
import {
  List,
  Avatar,
  Button,
  Typography,
  Form,
  Input,
  Select,
  DatePicker,
  Menu,
  Dropdown,
  Tabs
} from "antd";
import { DownOutlined } from "@ant-design/icons";

import "./App.css";
import logo from "./logo.svg";

const { Title } = Typography;
const { Option } = Select;
const { TabPane } = Tabs;

const todoListData = [
  {
    content: "图雀社区:汇聚精彩的免费实战教程",
    user: "mRcfps",
    time: "2020年3月2日 19:34",
    isCompleted: false
  },
  {
    content: "图雀社区:汇聚精彩的免费实战教程",
    user: "pftom",
    time: "2020年3月2日 19:34",
    isCompleted: false
  },
  {
    content: "图雀社区:汇聚精彩的免费实战教程",
    user: "Holy",
    time: "2020年3月2日 19:34",
    isCompleted: false
  },
  {
    content: "图雀社区:汇聚精彩的免费实战教程",
    user: "crxk",
    time: "2020年3月2日 19:34",
    isCompleted: false
  },
  {
    content: "图雀社区:汇聚精彩的免费实战教程",
    user: "Pony",
    time: "2020年3月2日 19:34",
    isCompleted: false
  }
];

const userList = [
  {
    id: "666666666",
    name: "图雀社区",
    avatar: "https://avatars0.githubusercontent.com/u/39240800?s=60&v=4"
  },
  {
    id: "23410977",
    name: "mRcfps",
    avatar: "https://avatars0.githubusercontent.com/u/23410977?s=96&v=4"
  },
  {
    id: "25455350",
    name: "crxk",
    avatar: "https://avatars1.githubusercontent.com/u/25455350?s=96&v=4"
  },
  {
    id: "23410977",
    name: "pftom",
    avatar: "https://avatars0.githubusercontent.com/u/23410977?s=96&v=4"
  },
  {
    id: "58352313",
    name: "holy",
    avatar: "https://avatars0.githubusercontent.com/u/58352313?s=96&v=4"
  }
];

const menu = (
  <Menu>
    <Menu.Item>完成</Menu.Item>
    <Menu.Item>删除</Menu.Item>
  </Menu>
);

const TodoInput = ({ value = {} }) => {
  return (
    <div className="todoInput">
      <Input type="text" placeholder="输入待办事项内容" />
      <Select style={{ width: 80 }} size="small" defaultValue="666666666">
        {userList.map(user => (
          <Option value={user.id}>{user.name}</Option>
        ))}
      </Select>
      <DatePicker
        size="small"
        style={{ marginLeft: "16px", marginRight: "16px" }}
      />
    </div>
  );
};

function TodoList() {
  return (
    <List
      className="demo-loadmore-list"
      itemLayout="horizontal"
      dataSource={todoListData}
      renderItem={item => (
        <List.Item
          actions={[
            <Dropdown overlay={menu}>
              <a key="list-loadmore-more">
                操做 <DownOutlined />
              </a>
            </Dropdown>
          ]}
        >
          <List.Item.Meta
            avatar={
              <Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
            }
            title={<a href="https://ant.design">{item.user}</a>}
            description={item.time}
          />
          <div>{item.content}</div>
        </List.Item>
      )}
    />
  );
}

function App() {
  const callback = () => {};

  const onFinish = () => {};
  const ref = useRef(null);

  return (
    <div className="App" ref={ref}>
      <div className="container header">
        <img src={logo} alt="" />
        <Title level={3}>图雀社区:汇聚精彩的免费实战教程</Title>
      </div>
      <div className="container">
        <Form onFinish={onFinish}>
          <Form.Item name="todo">
            <TodoInput />
          </Form.Item>
        </Form>
      </div>
      <div className="container">
        <Tabs onChange={callback} type="card">
          <TabPane tab="全部" key="1">
            <TodoList />
          </TabPane>
          <TabPane tab="进行中" key="2">
            <TodoList />
          </TabPane>
          <TabPane tab="已完成" key="3">
            <TodoList />
          </TabPane>
        </Tabs>
      </div>
    </div>
  );
}
 // ...
复制代码


上面的代码主要就是一系列初始数据的准备,antd 组件的使用,编写起来的大体轮廓,尚未涉及到任何的 TS 语法,但这个是咱们开始项目的基础,读者只须要进行简单的复制放进现有的 typescript-tea 项目中对应的 src/App.tsx  中便可。

准备样式部分


准备了逻辑代码以后,为了让咱们最后的待办事项在样式上更美观一点,也利于咱们讲解时的操做,咱们须要给项目加一点样式,打开 src/App.css 对其中的代码作出对应的修改以下:

.App {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-top: 60px;
}

.container {
  width: 600px;
}

.header {
  text-align: center;
  margin-bottom: 56px;
}

.header img {
  width: 160px;
  height: 160px;
  margin-bottom: 24px;
}

.todoInput {
  display: flex;
  flex-direction: row;
  align-items: center;
  height: 40px;
  border: 1px solid #434343;
}

.todoInput input {
  border: none;
}
复制代码


这个时候若是你的服务器还在运行,那么你应该能够看到以下效果:

image.png


好了!全部的准备工做已经就绪,在开始下一节真正的 TS 学习以前,咱们先来回顾一下咱们在这个小节中所完成的工做:

  • 使用 CRA 的 TypeScript 脚本初始化了一个 TS 版的 React 项目
  • 安装了 antd 组件库,并使用 react-app-rewired 替换默认的 react-scripts 来完成对 CRA 的 Webpack 配置进行修改,以是咱们能够得到 antd 组件的按需引用和主题定制的功能
  • 准备了初始待办事项代码的逻辑部分和样式部分


咱们在前面铺垫了大量的 TypeScript 的优势以及花了很多笔墨来准备初始代码,想必读到这里的读者们可能已经等不及要立刻见识一下 TS 的庐山真面目了吧!立刻就来啦!

想要学习更多精彩的实战技术教程?来图雀社区逛逛吧。

本文所涉及的源代码都放在了 Github  或者 Gitee 上,若是您以为咱们写得还不错,但愿您能给❤️这篇文章点赞GithubGitee 仓库加星❤️哦~

相关文章
相关标签/搜索