1. 程式人生 > >【demo】使用React+Webpackt做一個簡單的todolist

【demo】使用React+Webpackt做一個簡單的todolist

使用React實現一個簡單的todolist,實現基本的增刪功能

GitHub:https://github.com/heyue-99/todolist


建立專案

建立的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
              }]
      }
      ]}
};

執行 webpack-dev-server啟動webpack伺服器,使用瀏覽器開啟 http://127.0.0.1:8080就能看見。webpack-dev-server是為了監測前端檔案的變化,以便實時編譯打包前端檔案。

todolist

整體分析

React最大的賣點是輕量元件化。如果要分元件的話,我們大約可以分成一個總元件和兩個子元件。一個輸入內容的元件,一個顯示內容列表(帶刪除功能)的元件,外面再用一個總元件將兩個子元件包括起來。

顯示資料

既然是展示資料,首先要考慮資料儲存在哪裡,來自於哪裡。React提倡所有的資料都是由父元件來管理,通過props的形式傳遞給子元件來處理。

做一個todolist頁面需要一個父元件,兩個子元件。父元件當然就是todolist的總指揮,兩個子元件分別用來add和show、delete。

資料完全由父元件來管理和控制,子元件用來顯示、操作資料,得經過父元件的批准,父元件通過props的形式將資料傳遞給子元件,子元件拿到父元件傳遞過來的資料,再進行展示。

另外,根據React開發的規範,元件內部的資料由state控制,外部對內部傳遞資料時使用 props 。這麼看來,針對父元件來說,要儲存todolist的資料,那就是內部資訊(本身就是自己可控的資源,而不是『領導』控制的資源),用state來儲存即可。而父元件要將todolist資料傳遞給子元件,對子元件來說,那就是傳遞進來的外部資訊(是『領導』的資源,交付給你來處理),需要使用props。

新增資料

子元件得到資料後,就需要將新資料新增到todolist的資料中。而todolist的資料是由父元件來管理的,子元件不能說改就改呀,得申請父元件的允許和同意呀。因此,我們需要讓父元件開放一個可以修改資料的介面,然後將這個介面作為props傳遞給子元件,讓其能修改資料。

另外,子元件呼叫父元件的介面對todolist資料進行修改了之後,相當於修改了React物件的state資料,此時就會觸發React的自動更新(就是通過virtual-dom對比,然後更新真實的dom那一套),React會將UI實時隨著資料更新,就不用我們操心了,這也是React比較強大的地方之一。

刪除資料

刪除資料和新增資料,邏輯上是一樣的,都是需要父元件提供一個修改資料的介面,通過props形式傳遞給子元件,然後讓子元件來呼叫。

app.js

import React from "react";
import ReactDOM from "react-dom";
//import css from './style.css';
require('./style.css')

//TodoList元件是一個整體的元件,最終React也只渲染這個元件
//TodoList元件是兩個元件的集合
var TodoList = React.createClass({
	getInitialState: function(){
		return{
			todolist:[]
		};
	},

	handleAdd: function(mes){
		this.setState({
			todolist: mes
		});
	},

	render: function(){
		return(
				<div>
					<h2 className="top">react-todolist</h2>
					<TypeNew add={this.handleAdd} todo={this.state.todolist} />
					<ListTodo todo={this.state.todolist} del={this.handleAdd} />
				</div>
			);
	}
});



var TypeNew = React.createClass({
	addContent: function(e){
		e.preventDefault();
		var tet = this.refs.content.value.trim();
		if(tet!=''){
			this.props.todo.push(tet);
			this.props.add(this.props.todo);
		}
		this.refs.content.value='';
	},

	render: function(){
		return(
			<form onSubmit={this.addContent} className="form">
				<input type="text" ref="content" placeHolder="請輸入您的todolist" className="input" />
				<input type="submit" value="新增" className="add" />
			</form>
		);	
	}
});


var ListTodo = React.createClass({
	delContent: function(e){
		var i = e.target.getAttribute("data-index");
		this.props.todo.splice(i,1);
		this.props.del(this.props.todo);
	},

	render: function(){
		return(
			<ul id="todo-list">
			{
				this.props.todo.map(function(mes,i){
					return(
						<li className="content">
							<label>{mes}</label>
							<span className="del" onClick={this.delContent} data-index={i}>×</span>
						</li>
					);
				}.bind(this))
			}
			</ul>
		);
	}
});

ReactDOM.render(
	<TodoList />,
	document.getElementById("example")
);

加上style:
*{
	padding: 0;
	margin: 0;
}
body{
	background-color: #F5A22C;
	letter-spacing: 1px;
}
.top{
	text-align: center;
	margin-bottom: 20px;
	font-size: 26px;
}
.form{
	width: 430px;
	height: 50px;
}
.input{
	height:100%;
	width: 350px;
	border: none;
	font-size: 17px;
	padding-left: 10px;
	color: #8B8383;
}
.add{
	height: 100%;
	width: 60px;
	margin-left: 10px;
	background-color: #FB731F;
	border: none;
	color: white;
	font-size: 16px;
}
.add:hover{
	cursor: pointer;
}
.content{
	width: 420px;
	background-color: rgba(255,255,255,.3);
	margin-top: 20px;
	list-style: none;
	border-radius: 10px;
	padding-left: 10px;
	font-size: 17px;
	line-height: 60px;
}
.content .del{
	float: right;
	padding-right: 10px;
	color: #A19898;
}
.del:hover{
	cursor: pointer;
}
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>