preface

In my previous post, I wrote a summary of typescript usage and core concepts. This post will teach you how to use typescript in a project through a practical front end case study.

You will reap

  • How to use UMI to quickly build a React + ANTD + typescript front-end project
  • Middle background front-end project directory and TS file division
  • Use typescript in the React component
  • Use typescript in the tool library
  • Internet black and white wall case analysis

The body of the

Before we start, let’s take a lookCorporate black and white WallDemonstration of project:(Note: This article is only for project analysis and learning, not for any commercial use)

This project is a responsive site, adapted for BOTH PC and H5, and we’ll do a typescript anatomy of the site.

As you can see from the GIF above, the information structure of the website is roughly as follows:

Let’s move on to our text.

1. UseumiQuickly build a baseReact + antd + typescriptFront-end projects

Umi is a powerful and out of the box enterprise project scaffolding, here I directly use UMI to create a TS project, the specific method is as follows:

// 1. Create an empty directory $mkdir ts-react &&cdTs-react // 2. Create a project yarn create @umijs/umi-app // 3. The installation project depends on YARNCopy the code

Umi development requires only three simple commands. It is worth noting that the following interaction options will appear on the command line during step 2: For more information on how to create interactive command-line tools, see typescript and ANTDExploration and summary of front-end integration solutions based on react/ Vue ecologyThere is an introduction, interested in learning exchange.

The react + typescript + ANTD stack is supported by a skeleton project.

2. Middle background front-end project directory andtsFile partition

Let’s first take a look at the category division of the research projects:

├─ exercises - SRC │ ├─ assets │ ├─ ├─ ├─ SRC │ ├─ exercises │ ├─ ├.css │ ├─ index.tsx │ ├─ The ts │ ├ ─ layouts │ │ ├ ─ __tests__ │ │ │ └ ─ index. The test. The TSX │ │ ├ ─ index. The CSS │ │ └ ─ index. The TSX │ ├ ─ locales │ │ └ ─ En - US. Ts │ ├ ─ models │ ├ ─ pages │ │ ├ ─ __tests__ │ │ │ ├ ─ __mocks__ │ │ │ │ └ ─ umi - plugin - locale. Ts │ │ │ └ ─ Index. The test. The TSX │ │ ├ ─ about │ │ │ ├ ─ components │ │ │ ├ ─ index, which s │ │ │ ├ ─ but less │ │ │ └ ─ index. The TSX │ │ ├ ─ Index. CSS │ │ ├ ─ index. The TSX │ │ ├ ─ innerRec. The TSX │ │ └ ─ list. The TSX │ ├ ─ utils │ │ ├ ─ tool. The ts │ │ └ ─ the ts │ ├ ─ app. Ts │ └ ─ ├─ gps.css ├─ ├─ package.txt ├─ download.txt ├─ gps.txt ├─ download.txtCopy the code

The typings.d.ts and global.d.ts files are in the root directory of the project. In the former, we can put some global export modules, such as CSS,less, image export declarations, so we don’t have to re-declare them one by one in the page code, as follows:

// typings.d.ts
declare module '*.css';
declare module '*.less';
declare module "*.png";
declare module "*.jpeg";
Copy the code

This way we can avoid the TS error when importing CSS or image files into the page. For global.d.ts, I suggest putting some global declared variables, interfaces, etc., such as third-party library declarations like Jquery, global variable declarations under window, etc.

SRC directory (SRC directory)

  • Assets store static resources such as pictures, videos, and audio, and participate in the webpack packaging process
  • Layouts houses public layouts
  • Components stores global common components
  • Locales multilanguage configuration directory
  • Models DVA’s Models folder, which handles the Redux stream
  • Pages is a directory where pages are stored. It can contain page components, similar in structure to the global components
  • Utils stores common JS files such as js tool libraries, request libraries, etc

Now that you know the above directories and what they mean, let’s look at how to plan the TS files.

For a component library, there is a subdirectory corresponding to a component that contains the required style files, component TSX files, and the component’s own type file, named Type.ts, which contains the type and interface declarations required by the component.

Similarly, a page folder should have a similar structure, like the About page above, which contains the following structure:

  • Components The page’s proprietary component directory
  • Index.tsx Is the main file about the page
  • Index. less A style file for the page
  • Type. ts type and interface declaration file about the page

It is also important to note that if a page has a private type or interface declaration, we can declare it directly inside the file. We do not need to define and declare it outside.

Directory planning is almost complete, but the actual situation needs to be more structured according to its own project structure. Let’s take a look at the application of typescript in business code.

3. Use the React componenttypescript

Here I will use the project’s custom upload component and whitelist page as examples. The file upload component will use SFC(function component), and the whitelist page will use class component, so that you can get a complete understanding of typescript development in both component development modes.

3.1 Custom upload Component Development

The customized upload component is mainly applied in the publishing module, and the secondary encapsulation is based on ANTD so as to be compatible with the ANTD-supporting Form model, as shown below:

The implementation with typescript is as follows:

import React, { useState, useEffect, SFC, ReactNode } from 'react';
import { Upload, message } from 'antd';
import { LoadingOutlined, PlusOutlined } from '@ant-design/icons';
import styles from './index.less';

export interface BeforeUploadFunc {
  (file:File, fileList:FileList): boolean | Promise<File>;
}

export interface SuccessBack {
  (url: string) :string;
}

export interface ChangeFunc {
  (value: string | Array<string>) :void;
}

export interface IProps {
  action: string; listType? :string; showUploadList? :boolean; headers? :object; beforeUpload? : BeforeUploadFunc; onSuccess? : SuccessBack; withCredentials? :boolean; text? :string| ReactNode; imgUrl? :string; onChange? : ChangeFunc; value? :string;
}

const UploadCp:SFC<IProps> = (props:IProps) = > {
    const {
        listType = 'picture-card',
        showUploadList = false,
        action = 'http://io.cc.com/api/files/free',
        headers,
        beforeUpload = handleBeforeUpload,
        onSuccess,
        withCredentials = true,
        text = 'Upload cover',
        imgUrl,
        onChange,
        value
    } = props

  const [loading, setLoading] = useState(false)
  const [imageUrl, setImageUrl] = useState(imgUrl)

  const handleChange = (info:FileList):void= > {
    // Some operations
  }

  function handleBeforeUpload(file:File) :boolean {
    const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
    if(! isJpgOrPng) { message.error('You can only upload JPG/PNG file! ');
    }
    const isLt2M = file.size / 1024 / 1024 < 2;
    if(! isLt2M) { message.error('Image must smaller than 2MB! ');
    }
    return isJpgOrPng && isLt2M;
  }

  useEffect(() = > {
    !value && setImageUrl(imgUrl)
  }, [imgUrl, value])

  return <Upload
          name="file"
          listType={listType}
          className={styles.avatarUploader}
          showUploadList={showUploadList}
          action={action}
          withCredentials={withCredentials}
          headers={headers}
          beforeUpload={beforeUpload}
          onChange={handleChange}
        >
          {(value || imageUrl) ? <img src={value || imageUrl} alt="avatar" style={{ width: '100%' }} alt={text} /> : text}
        </Upload>
}

export default UploadCp
Copy the code

React uses the React function component. React provides the SFC function component with children built-in, so we don’t need to declare it explicitly. Others, such as function declaration, generic interface, optional type Settings, etc., are introduced in detail in the summary of TS core knowledge points and project case analysis in the last article. If you don’t, please feel free to talk to me in the comments section.

3.2 Whitelist page development

After looking at how functional components work with typescript, let’s look at class components. Let’s take the search list page as an example:

The code is as follows:

import React from 'react';
import { List, Avatar, Button, Skeleton, Tag, Modal } from 'antd';
import styles from './index.less';
import req from '@/utils/req';

export interface IProps extends Location {
  
}

interface List {
  name: string;
  img: string;
  desc: string; isLoading? :boolean;
}

interface LoadingState {
  initLoading: boolean;
  loading: boolean;
}

export interface IState extends LoadingState {
  data: Array<List>;
  list: Array<List>;
}

class LoadMoreList extends React.Component<IProps.IState> {
  state:IState = {
    initLoading: true.loading: false.data: [].list: [],};componentDidMount() {
    this.getData();
  }

  getData = () = > {
    req.get(`/blackwhite/get? type=The ${this.props.location.query.type}`).then((res:List) = > {
      this.setState({
        initLoading: false.data: res,
        list: res.slice(0, pageNum) }); })};render() {
    const { initLoading, loading, list, data } = this.state;
    return // Page implementation code}}export default LoadMoreList
Copy the code

The above code implements typescript for the class component, using inheritance for interface type declarations. You can also write type declarations without inheritance. You can also reuse common page types in separate type.ts directories.

4. Use it in the tool librarytypescript

After mastering typescript writing of class components and function components, let’s talk about typescript writing of tool classes. This part is relatively simple. The author simply lists several common tool functions and transforms them into typescript mode. The code is as follows:

// utils/tool.ts
/* * @Author: Mr Jiang.Xu * @Date: 2019-06-06 11:23:05 * @Last Modified by: Mr Jiang.Xu * @Last Modified time: The 2019-06-29 22:33:52 * /
 
/** * select */
export const isIe = ():boolean= > {
    let explorer = window.navigator.userAgent;
        // Check whether the browser is Internet Explorer
    if (explorer.indexOf("MSIE") > =0) {
        return true;
    }else {
        return false}}/** * Color conversion hexadecimal rGBA *@param {String} hex 
 * @param {Number} opacity 
 */
export function hex2Rgba(hex:string, opacity:number) :string {
	if(! hex) hex ="#2c4dae";
    return "rgba(" + parseInt("0x" + hex.slice(1.3)) + "," + parseInt("0x" + hex.slice(3.5)) + "," + parseInt("0x" + hex.slice(5.7)) + "," + (opacity || "1") + ")";
}

// Remove HTML tags
export const htmlSafeStr = (str:string) :string= > {
    return str.replace(/<[^>]+>/g."")}interface params {
  [propertyName: string] :string | number
}
/* Parses the URL argument */
export const toParams = (params:params):string= > {
    if(params){
        let query = [];
        for(let key in params){
            query.push(`${key}=${params[key]}`)}return `${query.join('&')}`
    }else{
        return ' '}}Copy the code

The above are a few simple cases, convenient for everyone to get started and understand, the actual work of the scene will be more complex, but master the basic declaration and definition mode, basically can solve most OF the TS declaration problem. As a front-end engineer, typescript makes a lot of sense. Although it adds complexity and learning costs to programming, in the long run, it has a positive impact on your team’s coding practices, problem location, project maintenance, and code management, so learning typescript is imperative.

The last

If you want to learn moreH5 game.webpack.node.gulp.css3.javascript.nodeJS.Canvas Data visualizationAnd other front-end knowledge and actual combat, welcome to the public number “interesting Talk front” to join our technology group to study and discuss together, explore the frontier of the front.

More recommended

  • TS core knowledge summary and project actual combat case analysis
  • How do we handle the front and back end configuration and request library encapsulation when it comes to cross-domain development (KOA/AXIOS)
  • Quickly implement SSR (server rendering) in your Vue/React application
  • Summary of several common sorting algorithms and search algorithms necessary for programmers
  • The front step from zero to one realizes unidirectional & bidirectional lists
  • Micro front-end architecture and my front-end technology inventory
  • Implementing a CMS full stack project from 0 to 1 based on nodeJS (part 1)
  • Implementing a CMS full stack project from 0 to 1 based on nodeJS
  • Vue and React
  • From zero to one teaches you to develop a component library based on VUE
  • Build front-end team component systems from 0 to 1
  • 15 minutes on javascript design patterns that front-end engineers must know (with detailed mind maps and source code)