内容简介:利用React/anu编写一个弹出层
本文将一步步介绍如何使用React或 anu 创建 一个弹出层。
React时代,代码都是要经过编译的,我们很多时间都耗在babel与webpack上。因此本文也介绍如何玩webpack与babel。
我们创建一个ui目录,里面添加一个package.json。内容如下,里面已经是尽量减少babel插件的使用了。
{
"name": "ui",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "RubyLouvre",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.24.1",
"babel-loader": "^6.4.1",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.16.0",
"webpack": "^2.2.1"
},
"dependencies": {
"prop-types": "^15.5.10",
"anujs": "^1.0.0"
}
}
如果你不想用anu,可以改成react与react-dom。
"dependencies": {
"prop-types": "^15.5.10"
"react": "^15.5.4",
"react-dom": "^15.5.4"
}
anu本身没有propTypes,而react最近的版本也把propTypes拆了出来,因此我们需要独立安装prop-types这个包。
webpack我们紧随时髦,使用2.0, 而babel则是一大堆东西。
然后我们在控制台 npm install 敲一下,会给我们安装上几屏的依赖,下面只是展示了一部分。可见前端的发展多么可怕,以前只是几个JS文件就觉得非常臃肿了,现在几百个习以为常。尽管它们大部分是预处理JS的。这也为React带来巨大的门槛,门槛越高,工资越高。
然后 ui目录下建立一个src目录,里面建toast.js。
//第一部分,引入依赖与定义模块内的全局变量
import React,{Component} from 'react';
import PropTypes from 'prop-types';
import ReactDOM from 'react-dom';
let singleton = null;
const container = document.createElement('div'),
defaultProps = {
show: false
},
propTypes = {
/**
* @property show
* @description 是否显示,默认false
* @type Boolean
* @default false
* @skip
*/
show: PropTypes.bool
};
document.body.appendChild(container);
//第二部分,定义组件
class ToastReact extends Component {
constructor(props) {
super(props);
this.state = {
show: this.props.show,
content: '',
autoHideTime: 2000
};
this._timer = null;
singleton = this;
}
shouldComponentUpdate(nextProps, nextState) {
this.setState({ show: nextState.show });
if (!!this._timer) {
clearTimeout(this._timer);
this._timer = null;
}
this._timer = setTimeout(() => this.setState({ show: false }), nextState.autoHideTime);
return true;
}
componentWillUnmount() {
clearTimeout(this._timer);
document.body.removeChild(container);
}
render() {
const { show, content } = this.state;
return (
<div
className="yo-toast"
style={{
display: show ? null : 'none'
}}
>{content}</div>
);
}
}
ToastReact.propTypes = propTypes;
ToastReact.defaultProps = defaultProps;
ReactDOM.render(<ToastReact />, container);
// 第三部分,一个代理对象,设置Toast的显示隐藏函数
/**
* Toast显隐函数
* @returns {Object}
*/
export default {
/**
* @method show
* @type Function
* @description 打开组件,显示传入的内容
* @param {String} content 组件显示的内容
* @param {Number} [autoHideTime] 内容显示的持续时间,默认2000ms
*/
show(content = 'no content', autoHideTime = 2000) {
singleton.setState({
content,
autoHideTime,
show: true
});
return this;
},
/**
* @method hide
* @type Function
* @description 关闭正在显示的组件
*/
hide() {
singleton.setState({ show: false });
return this;
}
};
整个文件分三部分,大家认真看注释。之所以将弹层变成单例模式,因此窗口通常只存在一个弹层。存在多个弹层的情况,大多数是设计不合理吧,比如说层上层。这种由于在React时代,数据都保存在redux中,因此当层上层出现时,原弹层的用法输入可以保存到redux中,然后再改变弹层的内容,就可以实现层上层的功能了。在jQuery时代,数据固化在dom里,无法剥离,才出现这奇葩的情况。
然后 我们再建一个app.js,里面模拟业务线的同学使用toast吧。
import Tooltip from './coast';
var btn = document.querySelectorAll('.demo');
btn[0].addEventListener('click', function() {
console.log('tooltip');
Tooltip.show('the tooltip autoHide after 2s');
}, false);
btn[1].addEventListener('click', function() {
console.log('tooltip 2')
Tooltip.show('the tooltip autoHide after 3s', 3000);
}, false);
btn[2].addEventListener('click', function() {
console.log('tooltip 3')
var tip = Tooltip.show('the tooltip will be hidden before the default time 2s');
setTimeout(()=>tip.hide(), 1000);
}, false);
然后在src的上一级目录,即我们原来ui 目录建一个index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>tooltip demo</title>
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<style>
.yo-toast {
position: fixed;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
min-width: 1rem;
max-width: 90%;
z-index: 1500;
height: 3rem;
padding: 20px 10px;
border-radius: .05rem;
background-color: rgba(0, 0, 0, .5);
color: #fff;
}
</style>
</head>
<body>
<button>normal tooltip</button>
<button>autohideTime tooltip</button>
<button>hide() tooltip</button>
</body>
</html>
我们准备在这个文件里引用我们的JS。JS必须要打包过的,babel处理过的。因此下面是重头戏,建立一个webpack.config.js
const webpack = require("webpack");
const path = require("path");
const fs = require("fs");
module.exports = {
context: __dirname,
entry: {
app: "./src/app.js"
},
output: {
path: __dirname + "/dist/",
filename: "[name].js"
},
module: {
rules: [
{
test: /\.jsx?$/,
loader: "babel-loader",
options: {
presets: ["es2015", "react"]
},
exclude: path.resolve(__dirname, "node_modules")
}
]
},
resolve: {
//如果不使用anu,就可以把这里注释掉
alias: {
react: "anujs/dist/React.js",
react: "anujs/dist/React.js",
"react-dom": "anujs/dist/React.js"
}
}
};
我们需要在resolve配置项上设置别名,anu一个JS文件就包含了react与react-dom的功能,体积又少,最适合线上使用。
我们敲下webpack命令,就发生成一个dist/app.js文件,然后 在index.html上引用它
<script src="./dist/app.js"></script>
最终效果图
本来还想把业务中用到的babel helpers分离出来,最后可耻的失败了,谁会麻烦给个参考项目给我。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Python Algorithms
Magnus Lie Hetland / Apress / 2010-11-24 / USD 49.99
Python Algorithms explains the Python approach to algorithm analysis and design. Written by Magnus Lie Hetland, author of Beginning Python, this book is sharply focused on classical algorithms, but it......一起来看看 《Python Algorithms》 这本书的介绍吧!