内容简介:利用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分离出来,最后可耻的失败了,谁会麻烦给个参考项目给我。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 利用 Powershell 编写简单的浏览器脚本
- [译] 利用 Immutability(不可变性)编写更为简洁高效的代码
- [译] 利用 Immutability(不可变性)编写更为简洁高效的代码
- 利用 Chromebook 来编写 Android 应用的过程变简单了
- 利用Python编写具有加密和解密功能的Burp插件 (上)
- 原 荐 利用Lombok编写优雅的spring依赖注入代码,去掉繁人的@Autowired
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Redis设计与实现
黄健宏 / 机械工业出版社 / 2014-6 / 79.00
【官方网站】 本书的官方网站 www.RedisBook.com 提供了书本试读、相关源码下载和勘误回报等服务,欢迎读者浏览和使用。 【编辑推荐】 系统而全面地描述了 Redis 内部运行机制 图示丰富,描述清晰,并给出大量参考信息,是NoSQL数据库开发人员案头必备 包括大部分Redis单机特征,以及所有多机特性 【读者评价】 这本书描述的知识点很丰富,......一起来看看 《Redis设计与实现》 这本书的介绍吧!