先看下效果图 项目地址:git.coding.net/Weishengyan…
效果图 环境准备:
安装node ,去官网下载安装,安装完自带npm包管理工具
使用到css工具:bulma、scss
友情链接bulma中文翻译:lqzh.me/bulma-docs-…
创建项目
npx create-react-app my-app
(npx 是一个帮你执行文件的工具,会自动查找当前依赖包中的可执行文件,如果找不到,就会去 PATH 里找。如果依然找不到,就会帮你安装!)
cd my-app
npm start
这个时候项目运行起来啦!
因为要用到bulma、scss,在项目目录下安装bulma、scss
npm install bulma node-sass --save
在项目public目录下的index.html文件中引入bulma的css
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.6.2/css/bulma.min.css"></link>
清空src目录,然后建一个TodoList文件夹、index.js文件 index.js文件内容为:
import React from 'react';
import ReactDOM from 'react-dom';
import TodoList from './TodoList/TodoList';
ReactDOM.render(<TodoList />, document.getElementById('root'));
在TodoList文件夹中新建一个TodoList.js文件,TodoList.scss文件
文件结构 TodoList.js文件内容为:
import React, { Component } from 'react'
class TodoList extends Component {
render() {
return (
<div>TodoList</div>
)
}
}
export default TodoList
这时候运行不会报错,页面会有“TodoList”
TodoList.js基本架构
import React, { Component, Fragment } from 'react'
import './TodoList.scss';
class TodoList extends Component {
constructor (props) {
super(props)
this.state = {
list: [],
inputValue: ''
}
// 绑定 this对象
}
handleInputChange = (e) => {
this.setState({
inputValue: e.target.value
})
}
handleClickAdd = () => {
if (this.state.inputValue === '') {
console.log('输入错误')
return 0
}
this.setState({
list: [...this.state.list,{
content:this.state.inputValue,
isEnd:false
}],
inputValue:''
})
console.log(this.state.list)
}
render() {
let EndNum = this.state.list.filter(item => item.isEnd === true)
return (
<Fragment>
<div className='container ContentBox'>
<section className="hero is-primary">
<div className="hero-body">
<div className="container">
<h1 className="title">
TodoList
</h1>
</div>
</div>
</section>
<div className="notification action">
<input
type="text"
className="input is-primary"
value={this.state.inputValue}
onChange={this.handleInputChange}
/>
<button className="button is-primary" onClick={this.handleClickAdd}>add</button>
</div>
<footer className="footer">
<p>共有:{this.state.list.length} 件事情</p>
<p>已完成:{EndNum.length}</p>
<p>未完成:{this.state.list.length - EndNum.length}</p>
</footer>
</div>
</Fragment>
)
}
}
export default TodoList
(css的样式可以在coding上面去复制,我这里就不展示出来了)
效果图 这个时候页面是这样的,可以打印出来
然后我们要给他添加子组件,在TodoList文件夹中创建TodoItem.js文件,在TodoList.js中import
子组件:
import React from 'react'
class TodoItem extends React.Component {
render() {
const {content,index,isEnd} = this.props
return (
<li className="content notification is-primary">
<label className="checkbox">
<input
type="checkbox"
/>
<span className="tag">{index + 1}</span>
{content}
<span
className={isEnd ? 'tag is-info' : 'tag is-warning'}
>
{isEnd ? '已完成' : '未完成'}
</span>
</label>
</li>
)
}
}
export default TodoItem
在父组件中添加函数
import TodoItem from './TodoItem' // 子组件
添加函数
getTodoItem() { // 获取子组件
return this.state.list.map((item, index) => {
return (
<TodoItem
key={index}
content={item.content}
isEnd={item.isEnd}
index={index}
/>
)
})
}
render()函数中
<ul className="notification list">{this.getTodoItem()}</ul>
插入位置 效果如下:
效果图
接下来我们给每个事项添加删除和修改状态的事件 父组件:
// 父组件通过属性的形式向子组件传递参数
// 子组件通过props接收父组件传递过来的参数
handleDelete = (index) => { // 删除
console.log(index)
const list = [...this.state.list]
list.splice(index, 1)
this.setState({
list
})
}
handleIsEnd = (index) => { // isEnd
let list = [...this.state.list]
list = list.map((item,itemIndex) => {
if (itemIndex === index) {
item.isEnd = !item.isEnd
console.log(item)
}
return item
})
this.setState({
list
})
}
getTodoItem() { // 获取子组件
return this.state.list.map((item, index) => {
return (
<TodoItem
deleteItem={this.handleDelete}
handleIsEnd={this.handleIsEnd}
key={index}
content={item.content}
isEnd={item.isEnd}
index={index}
/>
)
})
}
子组件:
// 子组件如果想和父组件通信,子组件要调用父组件传递过来的方法
handleDelete = () => { //删除
const {deleteItem, index} = this.props
deleteItem(index)
}
handleIsEnd = () => { // 是否完成
const {handleIsEnd, index} = this.props
handleIsEnd(index)
}
将方法加到jsx中
插入位置 好了 项目完成✅ 赶快试试吧!