本文实现 TodoList 各个组件的静态页面。
目标实现效果图:
组件代码结构:
入口文件 index.js
// file: src/index.js
// 引入 react 核心库
import React from "react";
// 引入ReactDOM
import ReactDOM from "react-dom";
// 引入组件
import App from "./App";
// 渲染App组件到页面
ReactDOM.render(<App />, document.getElementById("root"));
全局样式 App.css
/* file: src/App.css */
* {
margin: 0;
padding: 0;
}
html,
body {
background-color: #ffffff;
}
input[type="text"]:focus {
outline: none;
border: 1px solid #1890ff;
}
input[type="text"] {
box-sizing: border-box;
margin: 0;
padding: 0;
font-variant: tabular-nums;
list-style: none;
font-feature-settings: "tnum";
position: relative;
display: inline-block;
width: 100%;
height: 32px;
padding: 4px 11px;
color: rgba(0, 0, 0, 0.65);
font-size: 14px;
line-height: 1.5;
background-color: #fff;
background-image: none;
border: 1px solid #d9d9d9;
border-radius: 4px;
transition: all 0.3s;
}
.btn {
line-height: 1.499;
position: relative;
display: inline-block;
font-weight: 400;
white-space: nowrap;
text-align: center;
background-image: none;
border: 1px solid transparent;
box-shadow: 0 2px 0 rgb(0 0 0 / 2%);
cursor: pointer;
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
touch-action: manipulation;
height: 32px;
padding: 0 15px;
font-size: 14px;
border-radius: 4px;
color: rgba(0, 0, 0, 0.65);
background-color: #fff;
border-color: #d9d9d9;
}
.btn.btn-primary {
color: #fff;
background-color: #1890ff;
border-color: #1890ff;
text-shadow: 0 -1px 0 rgb(0 0 0 / 12%);
box-shadow: 0 2px 0 rgb(0 0 0 / 5%);
}
.btn.btn-primary:hover {
color: #fff;
background-color: #40a9ff;
border-color: #40a9ff;
}
.btn.btn-danger {
color: #fff;
background-color: #ff4d4f;
border-color: #ff4d4f;
text-shadow: 0 -1px 0 rgb(0 0 0 / 12%);
box-shadow: 0 2px 0 rgb(0 0 0 / 5%);
}
.btn.btn-danger:hover {
color: #fff;
background-color: #ff7875;
border-color: #ff7875;
}
.btn.btn-sm {
width: auto;
height: 24px;
padding: 0 4px;
font-size: 12px;
border-radius: 4px;
}
input[type="checkbox"] {
position: relative;
top: 1px;
}
ul {
list-style: none;
}
.todo-container {
width: 80%;
margin: 20px auto;
padding: 10px;
border: 1px solid #f0f0f0;
border-radius: 4px;
}
label + span {
margin-left: 4px;
}
input + span {
margin-left: 4px;
}
App 组件
// file: src/App.js
import React, { Component } from "react";
import Header from "./components/Header";
import List from "./components/List";
import Footer from "./components/Footer";
import "./App.css";
export default class App extends Component {
render() {
return (
<div className="todo-container">
<div className="todo-wrap">
<Header />
<List />
<Footer />
</div>
</div>
);
}
}
Header 组件
js 代码:
// file: src/components/Header/index.jsx
import React, { Component } from "react";
import "./index.css";
export default class Header extends Component {
render() {
return (
<div className="todo-header">
<input type="text" placeholder="请输入你的任务名称,按回车键确认" />
</div>
);
}
}
CSS 代码:
Header 组件使用到的 css 样式代码使用的代码在 App.css 文件中。
Item 组件
js 代码:
// file: src/components/Item/index.jsx
import React, { Component } from "react";
import "./index.css";
export default class Item extends Component {
render() {
return (
<li>
<label className="container">
<input type="checkbox" />
<span>xxxx</span>
</label>
<button className="btn btn-danger btn-sm" style={{ display: "none" }}>
删除
</button>
</li>
);
}
}
CSS 代码:
/* file: src/components/Item/index.css */
li {
height: 40px;
padding: 0 10px;
display: flex;
align-items: center;
justify-content: space-between;
border-radius: 4px;
}
li:not(:last-child) {
border-bottom: 1px solid #f0f0f0;
}
li:hover .btn {
display: inline !important;
}
li:hover {
background-color: #f8f8f8;
}
List 组件
js 代码:
// file: src/components/List/index.jsx
import React, { Component } from "react";
import Item from "../Item";
import "./index.css";
export default class List extends Component {
render() {
return (
<ul className="todo-main">
<Item />
<Item />
</ul>
);
}
}
CSS 代码:
/* file: src/components/List/index.css */
.todo-main {
margin: 10px 0;
border: 1px solid #f0f0f0;
border-radius: 4px;
}
Footer 组件
js 代码:
// file: src/components/Footer/index.jsx
import React, { Component } from "react";
import "./index.css";
export default class Footer extends Component {
render() {
return (
<div className="todo-footer">
<div>
<label>
<input type="checkbox" />
</label>
<span>
<span>已完成0</span> / 全部2
</span>
</div>
<div>
<button className="btn btn-danger">清除已完成任务</button>
</div>
</div>
);
}
}
CSS 代码:
/* file: src/components/Footer/index.css */
.todo-footer {
display: flex;
justify-content: space-between;
/* border-top: 1px solid #eee; */
padding: 8px 10px;
}
至此完成 TodoList 组件静态页面实现。