使用React实现一个微博发送表单
表单的需求:
(1)输入框获取焦点时,输入框边框变为橙色,右上角显示剩余字数的提示;输入框失去焦点时,输入框边框变为灰色,右上角显示热门微博。
(2)输入字数小于且等于140字时,提示显示剩余可输入字数;输入字数大于140时,提示显示已经超过字数。
(3)输入字数大于0且不大于140字时,按钮为亮橙色且可点击,否则为浅橙色且不可点击。
GitHub:https://github.com/heyue-99/weibo-form
创建项目
创建的todo
主要采用
node
包的方式,使用
webpack
打包
初始化项目并创建一些基础文件
初始化项目之后,就需要安装所需要的库及其依赖。npm安装方式可以为开发环境或生产选择所安装的依赖。
安装完所需要的依赖之后,配置webpack。
webpack.config.js:
var path = require("path");
module.exports = {
entry: {
app: ["./app/app.js"]
},
output: {
path: path.resolve("./build"),
filename: "main.js"
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['env','react']
}
}
},
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ]
},
{
test: /\.less$/,
use: [{
loader: "style-loader" // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
}, {
loader: "less-loader" // compiles Less to CSS
}]
}
]}
};
weibo-form
因为是一个简单的表单,所以不需要继续划分子组件
表单分为上中下三部分,包括热门微博和剩余字数的提示(title)
、
输入框(textarea)、
发布按钮(button)。
给 textarea
添加 onFocus
、onBlur
、onChange
事件,通过handleFocus
、handleBlur
、handleChange
来处理输入框获取焦点、失去焦点和输入。
然后将输入的内容的长度(length)放在在 state
里,这样每当内容发生变化时,就能方便的对变化进行处理(this.state.number)。
对于按钮的变化、热门微博和提示之间的转换,根据 state
中内容的变化来切换样式就能轻松地做到。
app.js
import React from "react";
import ReactDOM from "react-dom";
//import css from './style.css';
require('./style.css')
//TodoList组件是一个整体的组件,最终React也只渲染这个组件
var TodoList = React.createClass({
render: function(){
return(
<div>
<ListTodo />
</div>
);
}
});
var ListTodo = React.createClass({
getInitialState: function(){
return{
number: 0
};
},
addContent: function(e){
e.target.style.border = "2px solid #fa7d3c";
this.refs.link.style.display = "none";
this.refs.tip.style.display = "block";
},
handleBlur: function(e){
e.target.style.border = "2px solid #cccccc";
this.refs.link.style.display = "block";
this.refs.tip.style.display = "none";
},
handleChange: function(e){
this.setState({
number: e.target.value.length
});
},
render: function(){
return(
<div>
<div className="title">
<div ref="link">
<a href="#">三生三世十里桃花</a>
</div>
<div className="tip" ref="tip">
<span>{this.state.number<=140 ? '还可以输入' : '已超出'}<strong>{this.state.number<=140 ? 140-this.state.number : this.state.number-140}</strong>字</span>
</div>
</div>
<form>
<textarea onFocus={this.addContent} onBlur={this.handleBlur} onChange={this.handleChange}></textarea>
<input type="submit" value="发布" className={this.state.number>0 && this.state.number<=140 ? 'submit' : 'disabled'} disabled={this.state.number>0 && this.state.number<=140 ? '' : 'disabled'} />
</form>
</div>
);
}
});
ReactDOM.render(
<TodoList />,
document.getElementById("example")
);
style.css
.tip{
display: none;
}
textarea{
border: 2px solid #cccccc;
padding: 5px 5px;
width: 600px;
height: 100px;
box-sizing: border-box;
box-shadow: 0 0 2px rgba(0,0,0,0.15);
border-radius: 2px;
}
.title{
float: right;
margin-bottom: 10px;
}
.title a{
text-decoration: none;
color: #896FFC;
}
.title .tip{
color: #8B8A8A;
}
form .submit{
float: right;
width: 90px;
height: 30px;
font-size: 14px;
background: #ff8140;
border: 1px solid #f77c3d;
border-radius: 2px;
color: #fff;
box-shadow: 0px 1px 2px rgba(0,0,0,0.25);
margin-top: 10px;
cursor: pointer;
}
form .disabled {
float: right;
width: 90px;
height: 30px;
font-size: 14px;
background: #ffc09f;
color: #fff;
border: 1px solid #fbbd9e;
border-radius: 2px;
box-shadow: none;
margin-top: 10px;
}
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="example" style="width: 430px; margin: 100px auto;"></div>
<script type="text/javascript" src="/main.js"></script>
</body>
</html>