很长一段时间没有使用react做项目了,一看官网已经更新到17.x版本了,记得今年上班的时候才v13.x,由于平时项目开发用vue的时候居多,对于react长时间不用怕忘了,赶紧写个小案例练练手,使用版本说明:
- react:v17.0.1
- MDUI:v1.0.1
官方描述:MDUI 漂亮、轻量且好用,它能让你更轻松地开发 Material Design 网页应用。官网地址https://www.mdui.org/
先上效果图:
至于为啥使用MDUI,我也是在头条上刷资讯的时候偶然看见的,因为平时在上面也会看一些前端相关的,时不时的就会一些推送过来,在这之前我也不知道有MDUI,看了官网后,我觉得还挺好看,样式布局等只需要添加对应的类名就可以了,特别喜欢上面的按钮涟漪动画效果,只需添加一个简单类名 .mdui-ripple 就可以实现,这里就不过多介绍了,详情可看官网。
在实现过程中一些问题:
- 使用create-react-app创建项目后编译过程很慢,每次更改文件保存时编译需要3~4秒的时间,问题是我新创建项目后就一个组件todo.js,根据网上找的一些方法亲测有效,方法如下:
切换npm镜像,更换为淘宝的,然后删除node_modules包,重新cnpm install
npm config set registry http://registry.npm.taobao.org
- react动态添加与删除元素属性
vue的动态绑定属性很方便,但react没有这种方式的写法,需要引入createRef
//vue的用法:
<a :[key]="url"> ... </a>
//react的用法
import React, { Component, createRef } from "react";
export default class Demo extends Component {
state = { btn: createRef() };
render() {
return (
<div ref={this.state.btn}> 操作添加属性</div>
);
}
componentDidMount(){
//通过this.state.btn.current操作
//添加自定义属性,如data-id
this.state.btn.current.setAttribute('data-id','10')
//删除自定义属性
this.state.btn.current.removeAttribute("data-id");
}
}
注意,我这里使用的MDUI是用的cdn引入,需要在public文件下的index.html页面引入
<!-- MDUI CSS -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/mdui@1.0.1/dist/css/mdui.min.css"
integrity="sha384-cLRrMq39HOZdvE0j6yBojO4+1PrHfB7a9l5qLcmRm/fiWXYY+CndJPmyu5FV/9Tw"
crossorigin="anonymous"
/>
<!-- MDUI JavaScript -->
<script
src="https://cdn.jsdelivr.net/npm/mdui@1.0.1/dist/js/mdui.min.js"
integrity="sha384-gCMZcshYKOGRX9r6wbDrvF+TcCCswSHFucUzUPwka+Gr+uHgjlYvkABr95TCOz3A"
crossorigin="anonymous"
></script>
Todo.js全代码
import React, { Component, Fragment, createRef } from "react";
export default class Todo extends Component {
state = {
num: 0, //未完成任务数量
value: "", //输入的任务
list: [
//任务列表
{ id: "0", title: "阅读JavaScript权威指南第七版", check: false },
{ id: "1", title: "Css世界", check: false },
],
btn: createRef(),
};
render() {
return (
<div className="mdui-card mdui-container-fluid">
<div className="mdui-card-header">
<h2
className="mdui-card-header-title"
style={{ textAlign: "center" }}
>
todolist案例
</h2>
</div>
<div className="mdui-card-content">
<div className=" mdui-row">
<div className="mdui-textfield mdui-textfield-floating-label mdui-col-xs-6">
<label className="mdui-textfield-label">请输入任务</label>
<input
className="mdui-textfield-input"
type="text"
value={this.state.value}
onChange={this.getValue}
/>
</div>
<button
className="mdui-btn mdui-btn-raised mdui-ripple mdui-color-purple"
style={{ marginTop: "40px" }}
onClick={this.handleAdd}
ref={this.state.btn}
>
添加 +
</button>
</div>
<ul className="mdui-list">
{this.state.list.map((item, index) => {
return (
<Fragment key={item.title + index}>
<li className="mdui-list-item mdui-ripple">
<div className="mdui-list-item-content">
<label
className="mdui-checkbox mdui-text-color-purple"
style={{
textDecoration: item.check ? "line-through" : "none",
}}
>
<input
type="checkbox"
value={item.title}
onChange={this.handleCheck.bind(this, item)}
/>
<i className="mdui-checkbox-icon"></i>
{item.title}
</label>
</div>
<i
className="mdui-list-item-icon mdui-icon material-icons"
onClick={this.handleDelete.bind(this, item, index)}
>
clear
</i>
</li>
<li className="mdui-divider"></li>
</Fragment>
);
})}
</ul>
<div>
<button className="mdui-btn mdui-btn-raised mdui-ripple mdui-color-purple-a700">
未完成任务数量:<strong>{this.state.num}</strong> 个
</button>
</div>
</div>
{/* 未输入任务名的弹出层 */}
<div className="mdui-dialog" id="example-1">
<div className="mdui-dialog-title">任务名不能为空!</div>
<div className="mdui-dialog-content"></div>
<div className="mdui-dialog-actions">
<button className="mdui-btn mdui-ripple" mdui-dialog-confirm="true">
确定
</button>
</div>
</div>
</div>
);
}
//获取输入的任务名
getValue = (e) => {
this.setState({ value: e.target.value });
};
//添加任务
handleAdd = () => {
let { list, num, value } = this.state;
if (!value) {
this.state.btn.current.setAttribute(
"mdui-dialog",
"{target: '#example-1'}"
);
return;
} else {
this.state.btn.current.removeAttribute("mdui-dialog");
}
list.push({
id: this.state.num + 1,
title: this.state.value,
check: false,
});
this.setState({ list, num: num + 1, value: "" });
};
//删除任务
handleDelete(item, index) {
let { list, num } = this.state;
if (!item.check) {
num--;
}
list.splice(index, 1);
this.setState({ list, num });
}
//是否选择已完成
handleCheck(item, e) {
let { list, num } = this.state;
list.forEach((p) => {
if (p.title === item.title) {
p.check = e.target.checked;
}
if (item.check === false) {
this.setState({ num: num + 1 });
} else {
this.setState({ num: num - 1 });
}
});
this.setState({ list });
}
componentDidMount() {
let { num } = this.state;
this.state.list.forEach((item) => {
if (item.check === false) {
num++;
this.setState({ num });
}
});
}
}