创建一个简单的线上机器人商店

创建一个项目,使用TS模板:
添加TS模板: https://zh-hans.reactjs.org/docs/static-type-checking.html#adding-typescript-to-a-project
jsx简介:
https://zh-hans.reactjs.org/docs/introducing-jsx.html
(不管是原生js文件还是jsx文件,都没法直接在浏览器运行,而是需要babel转化es标准下的代码,项目中使用哪种类型的文件都是可以的。本项目使用TSX)
ts简单的来说就是给js加上了类型

结构

1.创建robot组件(tsx文件)

import React from "react";

interface RobotProps {
  id: number;
  name: string;
  email: string;
}
// 定义Robot为函数组件,<RobotProps>泛型类型,可写为{props},propt用来传递数据,此处使用解构赋值直接展开数据{ id, name, email }
const Robot: React.FC<RobotProps> = ({ id, name, email }) => {
  return (
    <li>
      <img alt="robot" src={`https://robohash.org/${id}`} />
      <h2>{name}</h2>
      <p>{email}</p>
    </li>
  );
};

export default Robot;

2.使用组件

import './App.css';
//导入机器人数据
import robots from './mockdata/robots.json'
import Robot from './components/Robot';
function App() {
  return (
   <ul>
     {robots.map(r => (
       <Robot id={r.id} email={r.email} name={r.name}/>
     ))}
   </ul>
  );
}

export default App;

机器人数据参考:
若无法识别json文件,可修改tsconfig.json解决,添加"moduleResolution": "node", "resolveJsonModule": true

[{
    "id": 1,
    "name": "Leanne Graham",
    "username": "Bret",
    "email": "Sincere@april.biz",
    "address": {
      "street": "Kulas Light",
      "suite": "Apt. 556",
      "city": "Gwenborough",
      "zipcode": "92998-3874",
      "geo": {
        "lat": "-37.3159",
        "lng": "81.1496"
      }
    },
    "phone": "1-770-736-8031 x56442",
    "website": "hildegard.org",
    "company": {
      "name": "Romaguera-Crona",
      "catchPhrase": "Multi-layered client-server neural-net",
      "bs": "harness real-time e-markets"
    }
  }]

image

样式

模组CSS文件

  • css文件与component文件放在同一目录下
  • 命名规范 *.module.css
    react默认构建了全局样式import'./index.css'
    import整个文件,默认会引入整个css文件,有可能会造成全局污染,我们可以按需引入import style from './index.css'
    以App.tsx作为案例处理css的模块化加载(隔离样式污染)
  1. 修改app.css的引用模式
    import'./App.css' 改为
    import styles from './App.css'
    typescript无法识别css格式的文件
    给css文件加上TS的定义声明
    .d.ts文件
    只包含类型定义,不包含逻辑
    不会被编译,也不会被webpack打包
declare module "*.css" {
  const css: { [key: string]: string };
  export default css;
}

声明所有.css后缀的文件,都会被定义为这种类型,接下来就可以通过访问对象的形式去使用css样式了。(JSS/CSS in JS)
2. 修改app.css为app.module.css
在react中,为了避免与es6中的类关键词class产生冲突,必须使用className关键词。
image

安装插件(可忽略)

npm install typescript-plugin-css-modules --save-dev
image
配置
image
本地编译器配置,添加.vscode文件夹,添加settings.json文件
文件中输入:

{
	"typescript.tsdk": "node_modules/typescript/lib",
	"typescript.enablePromptUseWorkspaceTsdk": true
}

配置完成后,会发现多了提示功能:
image

补充代码

以同样的方式给robot.tsx文件添加模块化样式,代码如下:

.cardContainer {
    display: flex;
    flex-direction: column;
    background-color: #00BDAB;
    border: 1px solid grey;
    border-radius: 5px;
    padding: 25px;
    cursor: pointer;
    backface-visibility: hidden;
    transform: translateZ(0);
    transition: transform 0.25s ease-out;
}

.cardContainer:hover {
    transform: scale(1.05);
}

image

加载媒体资源与字体

建立存储静态资源的目录结构
image
媒体资源可直接引用:

import logo from './assets/images/logo.svg'
<img src={logo} alt="logo" className={styles.appLogo} />

(window系统,点击ctrl+鼠标点击logo,可以进入到react-app.d.ts文件,可以看到react已经默认定义了svg在内的一些文件类型)
字体资源:
搜索免费字体,随意下载字体资源.tff文件
在index.css文件中定义为全局字体

@font-face {
    font-family: 'Slidefu';
    src: local('Slidefu'), url(./assets/fonts/Slidefu-Regular-2.ttf) format('truetype');
}

标题一使用该字体:

h1 {
    font-family: 'Slidefu';
    font-size: 72px;
}

补充App文件样式代码:

.app {
    text-align: center;
}

.appHeader {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
    margin-top: 36px;
    margin-bottom: 24px;
}

.appLogo {
    height: 10vmin;
    pointer-events: none;
}

h1 {
    font-family: 'Slidefu';
    font-size: 72px;
}

@media (prefers-reduced-motion: no-preference) {
    .appLogo {
        animation: App-logo-spin infinite 20s linear;
    }
}

.robotList {
    width: 85vw;
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr;
    grid-gap: 20px;
}

image

image

posted @ 2022-02-21 11:17  黑蛋的博客  阅读(245)  评论(0编辑  收藏  举报