博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ReactJS实践(一)—— FrozenUI React化之Loading组件
阅读量:7115 次
发布时间:2019-06-28

本文共 5521 字,大约阅读时间需要 18 分钟。

在前面我们通过四篇文章入门了React的大部分主要API,现在则开始进入实践环节。

实践系列的开篇打算拿我司的FrozenUI来试验,将其部分UI组件进行React化,作为第一篇实践文章,将以较简单的来入手,官网demo的效果如下图:

为了更好地开发,后续将以webpack工具来辅助,对其不了解的童鞋可以先查阅我的一文。

鉴于我们将复用 FrozenUI 的样式,所以在DOM结构、class命名上都应当尽量和原版的保持一致,在这个基础上来实现具有同样功能的React组件。

于是我们先下载好 (方便示例所以直接用全局的样式)和图片资源,并定义一个简单的 webpack.config.js:

module.exports = {        entry: {            loading : './src/js/page/loading.js'        },        output: {            path: 'dist/js/page',            filename: '[name].js'        },        module: {            loaders: [                { test: /\.css$/, loader: 'style-loader!css-loader' },                { test: /\.js$/, loader: 'jsx-loader?harmony' },                { test: /\.scss$/, loader: 'style!css!sass?sourceMap'},                { test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192'}            ]        },        resolve: {
extensions: ['', '.js', '.json', '.scss'] } };

需要下载的模块大致有这些(尽管有几个我们暂时还用不上,先装上无所谓)

"dependencies": {    "css-loader": "^0.15.2",    "expose-loader": "^0.7.0",    "file-loader": "^0.8.4",    "jsx-loader": "^0.13.2",    "node-sass": "^3.2.0",    "react": "^0.13.3",    "sass-loader": "^1.0.2",    "style-loader": "^0.12.3",    "url-loader": "^0.5.6"  }

我们的文件目录结构也很简单:

其中 src 为源文件文件夹,dist 用于存放 webpack 最终处理后的输出文件。

src/js 中又分了 component 和 page 两个文件夹,用于存放组件脚本和html页面上要引用的入口脚本。

 

./loading.html

这是最终执行页面,作为Demo可以做的简单点:

  
Demo

其中类名为wrap的div是方便我们挂载Loading组件的容器,整个页面也只有一个script脚本入口(样式也将最终打包在里面)

./src/js/page/loading.js

我们先写好该页面入口脚本,确定好Loading组件的使用锥形:

require('../../css/frozen.css'); //把样式引进来var React = require('react'),    Loading = require('../component/Loading'); //这是组件模块,下一步要写的东西var wrap = document.querySelector('.wrap'),    hideCallback = function(){  //卸载组件后的回调        alert('done!!');    };React.render(    
, wrap);setTimeout(function(){ //3秒后卸载组件,模拟触发回调 React.unmountComponentAtNode(wrap)}, 3000);

我们希望能够自定义Loading组件上所显示的文字,以及它被隐藏掉时触发的回调,故我们使用两个props——“content”和“onHide”来绑定(事实上还有一个判断是否只在局部显示“加载中”的props属性“isPart”,但新版的FrozenUI取消了该功能)

./src/js/component/Loading.js

这块是Loading组件模块,是最重要的模块,用于实现Loading组件的全部功能。

注意常规我们要求React组件模块的首字母必须大写。

初步写出一个简单的组件结构:

var React = require('react'),        PropTypes = React.PropTypes;    var Loading = React.createClass({        propTypes: {
onHide: PropTypes.func, //组件卸载后的回调 content: PropTypes.string // 展示内容 }, componentWillUnmount: function(){ //卸载时的回调 if(typeof this.props.onHide === 'function'){ setTimeout(this.props.onHide, 10); } }, render: function () { var content = this.props.content || '正在加载中...', component = (
{content}
); return component } }); module.exports = Loading;

对于两个绑定的props,我们分别在 componentWillUnmount 和 render 中做了对应处理,从而决定了组件卸载时是否触发回调,以及加载时显示什么内容(若未传props.content,则默认为“正在加载中...”),接着我们要处理的是最终渲染的DOM结构(总不能只有一个div对吧),这块我们得分析现有的 Frozen-Loading组件的DOM结构,尽量与其一致(包括类名的定义):

那么我们只需要在 render 里直接套用这块DOM结构,把<p>标签里的内容换成 {content} 即可。

不过这样好像太简单了,不怎么好玩呢~

在上个版本的Frozen-Loading组件里,是有区分全局展示/局部展示加载界面的,局部加载是酱紫的:

我还记得局部展示情况下的DOM结构和样式(实际上它们只是类名不同),于是打算增加个 props.isPart 来判断用户是否要局部展示,并且这样改写组件代码:

var React = require('react'),        loadingCN = require('../component/styleMaps').loadingCN, //引入加载组件类名对象        PropTypes = React.PropTypes;    var Loading = React.createClass({        propTypes: {            isPart: PropTypes.bool, //是否局部加载            onHide: PropTypes.func,  //组件卸载后的回调            content: PropTypes.string  // 展示内容        },        componentWillUnmount: function(){            if(typeof this.props.onHide === 'function'){                setTimeout(this.props.onHide, 10);            }        },        render: function () {            var content = this.props.content || '正在加载中...',                flag = this.props.isPart ? 'partial' : 'global',                component = (

{content}

); return component } }); module.exports = Loading;

留意一个比较有趣的地方,我们通关一个变量flag来判断用户是希望全局显示还是局部显示加载界面,然后通过这个标签来获取到对应的类名:

flag = this.props.isPart ? 'partial' : 'global',                component = (

{content}

);

而此处的 loadingCN 是我们在开头引入的一个共用模块:

loadingCN = require('../component/styleMaps').loadingCN

该模块的定义也非常简单:

./src/js/component/styleMaps.js

module.exports = {        globalCN: {},        loadingCN: {            block: {                partial: 'demo-block',                global: 'ui-loading-block show'            },            wrap: {                partial: 'ui-loading-wrap',                global: 'ui-loading-cnt'            },            i: {                partial: 'ui-loading',                global: 'ui-loading-bright'            }        }    };

其返回了一个存放各组件类名对象,因此我们可以通过 require('../component/styleMaps').loadingCN.block['global'] 的形式来获取到Loading组件全局加载时最外层div的类名。

于是乎我们为啥要这么折腾多搞个样式模块呢?直接写在 Loading.js 里不行么?

答案是可以,但是多出一个样式模块可以方便我们后期统一在一个文件里维护所有组件的类名,实际上是为后期维护提供了一定便捷度。

另外该样式管理模块我们也暂时腾出了一个叫 globalCN 的对象属性,可以作为存放多个组件间共用的类名。

我们执行 webpack 打包后访问根目录的 loading.html(模拟移动端),效果正合我们预期呢:

我们给 page/loading.js 要渲染的组件加上 isPart={true} ,让其走局部加载形式:

React.render(    
, wrap);

运行结果也是666:

本次的实践就这么愉快的结束吧~ 本节的代码可以在下载到。

下次分享下稍复杂点的 Tab 面板的React化的实现。共勉~!

如果觉得有帮助,就帮忙点下推荐吧,不然感觉每次写这种系列的文章好吃亏都没人支持。。。都不太想继续写了\("▔□▔)/

donate

转载地址:http://yeghl.baihongyu.com/

你可能感兴趣的文章
android之间传递list
查看>>
要注意一下xss攻击啊
查看>>
android模拟器(genymotion)+appium+python 框架执行基本原理(目前公司自己写的)...
查看>>
Java并发编程-总纲
查看>>
mac android 安装 apk
查看>>
win2008开启和禁止PING
查看>>
金融学英语
查看>>
ORACLE之SQL语句内部解析过程【weber出品】
查看>>
Android预安装可卸载程序
查看>>
C++多态与虚函数
查看>>
javascript中数组的深拷贝的方法
查看>>
html5,表单的综合案例
查看>>
html5css练习 旋转
查看>>
孙式太极拳的站桩(作者:孙剑云)
查看>>
Java跟C.C++相互调用
查看>>
Lua函数之一
查看>>
消息发送机制的利用
查看>>
Android 获取屏幕宽高
查看>>
Android系统启动过程详解【转】
查看>>
常看本地是否安装Git和maven工具
查看>>