背景

随着互联网世界的兴起,web前端开发的方式越来越多,出现了很多种场景开发的前端架构体系,也对前端的要求日益增高,早已经不是靠一个JQuery.js来做前端页面的时代了,而今移动端变化最大,近两年出现了React-lite.js,Vue.js,ReactNative,Weex...等一些开发方式,早期移动web端大多数基于sea.js模块化去开发,而我更倾向于组件化方式去开发,因为组件化的独立性才是为后期业务扩展,降低代码维护成本的最佳方案。

针对移动web端组件化,本人这次引用了古映杰开发的react-lite.js来做,具体用什么方式去做?我下面一一介绍。

首先什么是web组件化?

1.组:组合的方式

2.件:原子性质

本人的理解是根据业务场景和UED设计结合抽象出来具有独立性、共用性及扩展性的Html+CSS+javascript的结合体。

什么是JSX?

            参考http://www.cnblogs.com/kuailingmin/p/3996406.html

为什么用react.js组件化方式去做移动web端?

1.让代码层逻辑独立起来,尽量不要出现有很多js文件存在关联,这样写多了业务场景,后期维护成本提升,因为“蜘蛛网变大,变的密集了”

2.利用react.js中生命周期来提升业务逻辑的扩展能力,用react.js中的Virtual DOM来提升页面渲染的性能

3.react.js也提供了对SEO友好的方式

4.能跨多平台开发,并能开发多种类型的前端场景,比如数据可视化,单页面应用,网页游戏。。。

5.rendering更新可达到60fps(60fps是动力也是压力,因为它意味着只有16.7毫秒(1000 / 60)来绘制每一帧)

6.可组合,可重用、可维护

7.制定了独有的代码编写规范,制约了代码编写结构不清晰,混乱的现象。

而今随着node.js环境开发的兴起,我们项目中也采用了node.js的方式去做整体前端架构,这样一来,对于前端组件化这块多了很多好处。

  1. 可以使用npm下载很多js开发的工具包,丰富我们很多前端应用的开发
  2. 通过npm下载babel,对JSX的支持和es6的语法糖转译,我们就可以放心的去用es6的语法去写react.js的代码
  3. 通过node.js提供的ejs模版也不失SEO友好
  4. 不用担心cpu主进程的膨胀,因为就node.js就一个主进程,很多个子进程。

下面进入我的移动web方案主题:

从上图主要有几个重要点:

1.项目是在node.js环境中开发的

2.从ejs模版返回出html字符串给浏览器渲染

3.ejs模版中引用的js文件已经是已react-lite方式打包后的并通过babel转译es6和jsx语法糖的压缩版js

4.css文件和js文件都放在CDN中的,通过ejs模版引入

5.获取数据通过ajax发送请求到node.js环境去调用对应的接口。

先从用react.js方式做移动web端组件化开始,首先要明确一点,项目不是用react.js最终打包压缩的js!做法是在编写代码方式上以react.js语法去写,该怎么创建组件,该怎么处理父子组件之间的通信,还是react.js方式正常去写,关键在最后生成压缩js则通过react-lite来进行,如果纯react.js打包压缩文件体积还是很大的,第一次加载性能上稍有影响,但加载完之后的UI操作却很顺畅,我们曾经尝试过纯react.js来做一个移动web端的频道页,对于3G,4G 的移动用户来说真的看不出什么变化。

先来了解下react.js的组件化写法,怎么去创建一个react.js组件:

1.在页面要定义一个Html DOM来接收react.js定义的组件内容,例子中id为mian的就是组件容器:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <div id="main"></div>
  9. </body>
  10. </html>

这里我们创建一个div并设置一个id 这个id就是我们react组件要引用到的

2.看看js里面怎么去定义组件

  1. import React from "react";
  2. import ReactDom from "react-dom";
  3.  
  4. class Index extends React.Component{
  5. render(){
  6. return (
  7. <h1>Hello!</h1>
  8. )
  9. }
  10. }
  11.  
  12. ReactDom.render(<Index />,document.getElementById("main"));

很直观的看到3层定义,第一层先引用react.js的包,第二层class自定义一个react组件,第三层用ReactDom.render将渲染的组件内容绑定到对应的html dom元素中 去。

这就形成了react组件雏形,会点js一看都会很快明白。吐槽一下:如果这样return  Html DOM都看不懂的话,只能说你不适合写js。组件的雏形定义好了,接下来该怎么办呢?react提供了一些机制,这里介绍2个最主要的特性,也是常用关键点,一个是生命周期,另一个是虚拟DOM!

  React生命周期:

在react.js中定义了一套生命周期的体现,这种形式是以前js框架中没有的,react的生命周期给我传递一个很直观的逻辑场景,从组件渲染之前到组件渲染之后,从第一次组件渲染到第二次组件渲染的生命周期变化,都分的很有条理,还给我最大的感受就是针对多种业务场景都能游刃有余的处理,生命周期真心很赞。感慨就到此,上图:

react.js生命周期分4种流程:

1.首次渲染:

getDefaultProps

getInitialState

componentWillMount

render

componentDidMount

2.当属性props发生变化

componentWillReceiveProps

shouldComponentUpdate

componentWillUpdate

render

componentDidUpdate

3. 当状态state发生变化

shouldComponentUpdate

componentWillUpdate

render

componentDidUpdate

4.销毁

componentWillUnmount

有人直接看到会很懵,不要紧,下面对每个函数做一个解释,就会帮你很容易的理解了:

getDefaultProps:组件创建之前会先调用,全局性只有一次性

getInitialState:初始化组件状态

componentWillMount:组件渲染之前调用,在这里可以做一个对默认属性,默认状态,和组件渲染之前的逻辑操作

render:渲染组件,此操作会生成一个虚拟DOM存在内存中

componentDidMount:组件渲染之后的操作,根据业务场景而定,如果有操作在此函数中处理即可

componentWillReceiveProps:当组件中的默认属性props发生了变化,此方法被调用到

shouldComponentUpdate:组件接收到新的props或者state的时候调用,此函数返回值决定着原来的组件结构是否重新渲染

componentWillUpdate:组件第二次渲染之前调用

componentDidUpdate:组件第二次渲染之后调用

componentWillUnmount:组件销毁时调用

这些都是react.js规范好的操作流程,从命名上可以看出带有"will"的函数都是在render之前调用,带有"Did"都是在render之后调用,有个这样一个形式,在操作组件UI或扩展业务场景方便了很多。看一下在代码中是怎么呈现组件生命周期定义的:

  1. import React from "react";
  2. import ReactDom from "react-dom";
  3.  
  4. class Index extends React.Component{
  5. getDefaultProps(){
  6. //初始化属性
  7. }
  8. getInitialState(){
  9. //初始化状态
  10. }
  11. componentWillMount(){
  12. //组件第一次渲染之前调用
  13. }
  14. componentWillReceiveProps(){
  15. //当初始化属性发生变化调用
  16. }
  17. shouldComponentUpdate(){
  18. //组件接受到新属性或者新状态的时候调用
  19. }
  20. componentWillUpdate(){
  21. //第二次渲染之前调用
  22. }
  23. componentWillUnmount(){
  24. //销毁操作,在真正组件删除之前调用
  25. }
  26. render(){//渲染
  27. return (
  28. <h1>Hello!</h1>
  29. )
  30. }
  31. componentDidMount(){
  32. //渲染之后调用
  33. }
  34. componentDidUpdate(){
  35. //第二次渲染之后调用
  36. }
  37. }
  38.  
  39. ReactDom.render(<Index />,document.getElementById("main"));

接下来再看一个react.js核心虚拟DOM,这是react.js为什么能让世界接收它的最重要原因,react.js团队首创了这个革命性的想法,在现在有些js框架也开始加入虚拟DOM概念,比如vue.js2.0。在我对虚拟DOM的认知总结一句话:“就是用耍小聪明的手段简化了浏览器对DOM重复渲染的操作,耍的漂亮!”;

React虚拟DOM:

       Virtual DOM是react的精髓,不仅是页面渲染性能提升,最主要的是对DOM一层抽象,这种方式颠覆了我们对前端DOM渲染的观念,可能在浏览器端开发感觉不是很直观,而在ReactNative中开发中,这层抽象的意义变大了,在app端开发没有dom存在,而react这样的方式可以编译OC组件或者安卓的组件。总结虚拟DOM几个概念:

1.react.js创建一个组件render之后生成一个虚拟dom(纯粹的一个js数据结构)放在内存中

2.如果react组件发生变化时,新的Virtual DOM和老的Virtual DOM进行对比,将变得部分批量更新到真实DOM里面去

3.老的方式如果DOM发生了变化,大多数是将页面DOM元素重新刷新一边之后数据也更新了,而虚拟dom想法是让js模拟真实DOM结构,然后在js层面做前后对比,用这样方式效率肯定是很高的,js层面工作对比完成后,再改变真实DOM,这就是快的方式。

React-lite:

上面是介绍了react.js中2大概念,就相当一个战士一只手握着剑(虚拟DOM),一只手拿着盾(生命周期),有了这样的装备战士才能够冲进战场去作战。也了解了react组件的封装。这样正常开发就已这样方式去写代码逻辑,最终还要经过webpack打包操作的,在这个打包过程中用react-lite.js替换掉react.js,这样既简单,又减少了文件大小,并保持了生命周期和虚拟DOM主要机制。客观的讲也许不是首次加载最好的,但保证是操作UI最流畅,二次渲染最快的。react-lite最直接的解释就是移动版react.js

体积小:


reat-lite与react区别:

1.react.PropType方法弃用

2.react.js可在服务端渲染,react-lite在浏览器端渲染

3.为了保证百分百的移植性,react-lite.js函数命名都和react.js保持一致

4.保持react.js中的虚拟DOM,生命周期等机制

reat-lite用法:

用法很简单,快捷,只要在webpack中打包做一些小的操作即可,先上代码看吧

  1. var webpack = require('webpack');
  2. //打包less插件
  3. var ExtractTextPlugin = require('extract-text-webpack-plugin');
  4. //这里的'./css/bundle.css'设置打包地址
  5. var ExtractLess = new ExtractTextPlugin('./css/bundle.css');
  6. //打包多个文件插件
  7. //var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('common.js');
  8. var path = require('path');
  9. module.exports = {
  10. entry:[
  11. './react/star/app.js'
  12. ],
  13. output:{
  14. path:'./zip/channels/star',
  15. filename:'star.pak.js'
  16. },
  17. module:{
  18. loaders:[
  19. {test: /\.js$/, exclude: /(node_modules|bower_components)/, loader: 'babel',query:{presets:['es2015','react']}},
  20. {test:/\.less$/,loader:ExtractTextPlugin.extract("style-loader", "css-loader!less-loader")},
  21. //图片文件使用 url-loader 来处理,小于8kb的直接转为base64
  22. { test: /\.(png|jpg)$/, loader: 'url-loader?q=8192'}
  23.  
  24. ]
  25. },
  26. resolve:{
  27. extensions:['','.js'],
  28. alias:{
  29. 'react':'react-lite',
  30. 'react-dom':'react-lite'
  31. }
  32. },
  33.  
  34. plugins:[
  35. ExtractLess,
  36. new webpack.optimize.UglifyJsPlugin({
  37. compress:{
  38. warnings:false
  39. },
  40. mangle:{
  41. except:['$super','$','exports','require']
  42. }
  43. })
  44. ]
  45. };

在resolve中配置alias属性,将react和react-dom全部跟换react-lite即可。一步实现react和react-lite的切换,注意webpack打包的时候会出现抛error的现象,

但是webpack提供了UglifyJsPlugin插件,帮我们很好的处理了这种打包异常,具体介绍可以看一下http://www.cnblogs.com/kuailingmin/p/5643658.html

 总结:

一种技术二种方式,编写代码以react.js方式去做,打包用react-lite.js方式压缩文件,简化了js体积,实现了PC移植到移动web端的过程,成功将react.js原有的组件化方式保留并在移动web端实现应用。

移动web端的react.js组件化方案的更多相关文章

  1. atitit.React   优缺点 相比angular react是最靠谱的web ui组件化方案了

    atitit.React   优缺点 相比angular react是最靠谱的web ui组件化方案了 1. React的组件化才是web ui部件的正确方向1 1.1. 组件化集成html ,css ...

  2. vue.js组件化开发实践

    前言 公司目前制作一个H5活动,特别是有一定统一结构的活动,都要码一个重复的轮子.后来接到一个基于模板的活动设计系统的需求,便有了下面的内容.借油开车. 组件化 需求一到,接就是怎么实现,技术选型自然 ...

  3. VUE.JS组件化

    VUE.JS组件化 前言 公司目前制作一个H5活动,特别是有一定统一结构的活动,都要码一个重复的轮子.后来接到一个基于模板的活动设计系统的需求,便有了下面的内容.借油开车. 组件化 需求一到,接就是怎 ...

  4. Vue.js:轻量高效的前端组件化方案

    转发一篇尤老师对vue.js的介绍,了解vue.js的来龙去脉.不过现在已经是2.0了,也有添加一些新的东西,当然有些东西也改了. Vue.js:轻量高效的前端组件化方案 Vue.js 是我在2014 ...

  5. Web框架概述——React.js

    目前,在前端Web开发中,三大热门框架为React.js,Vue.js,Angular.js .当然,三大框架各有各的优缺点,这里就不多说了,下面我就针对前段时间所学的React框架做一下整体知识点的 ...

  6. React 面向组件化编程 - 封装了webpack - npm run build 产生的包的 /static 引用路径问题

    React 面向组件化编程 面向对象 ----> 面向模块 ----> 面向组件 套路: 注意: 组件名必须大写开头: 只能有一个根标签: <input />虚拟DOM 元素必 ...

  7. js组件化(转载)

    今天想着开始封装自己的UI库和组件库,从网上看到一篇很好的关于js组件化的文章,现在分享一下. 转载地址:https://blog.csdn.net/Prince_fmx/article/detail ...

  8. iOS应用架构谈 组件化方案

    转载: iOS应用架构谈 组件化方案 简述 前几天的一个晚上在infoQ的微信群里,来自蘑菇街的Limboy做了一个分享,讲了蘑菇街的组件化之路.我不认为这条组件化之路蘑菇街走对了.分享后我私聊了Li ...

  9. iOS 组件化方案

    概述 近一年iOS业界讨论组件化方案甚多,大体来说有3种. Protocol注册方案 URL注册方案 Target-Action runtime调用方案 URL注册方案据我了解很多大公司都在采用,蘑菇 ...

随机推荐

  1. D3.js学习(二)

    上一节中我们已经画出了一个基本的图表,不过忘了给坐标轴添加标签了,所以在本节中我们要给坐标轴加上标签,目标效果如下 给X轴添加标签 很明显,标签是不是一个text内容块啊,所以我们只要在svg中添加一 ...

  2. python画决策树

    1.安装graphviz.下载地址在:http://www.graphviz.org/.如果你是linux,可以用apt-get或者yum的方法安装.如果是windows,就在官网下载msi文件安装. ...

  3. ElasticSearch+ElasticGeo+Geoserver发布ES地理数据

    依赖GeoserverElasticSearchElasticGeo部署部署ElasticGeo使用创建ES数据源并发布发布 依赖 Geoserver 环境搭建参考: ElasticSearch 环境 ...

  4. 8. vim编辑器高级应用

    1. vim主要模式介绍 命令模式.命令行模式.编辑模式 字符操作:i 当前插入, I行首插入, a当前字符之后插入,A行首插入, ESC退出当前模式 2. vim命令模式 3. vim插入模式 4. ...

  5. bootstrap 布局(收藏/摘抄)

    bootstrap 12栅格 布局

  6. Session、Cookie--2017年1月3日

    Session Session 对象用于存储用户的信息.存储于 session 对象中的变量持有单一用户的信息,并且对于一个应用程序中的所有页面都是可用的.    Session 对象 当您操作某个应 ...

  7. ACM/ICPC 之 Dinic+枚举最小割点集(可做模板)(POJ1815)

    最小割的好题,可用作模板. //Dinic+枚举字典序最小的最小割点集 //Time:1032Ms Memory:1492K #include<iostream> #include< ...

  8. OC编程之道-创建对象之抽象工厂方法

    定义:提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类.       <AbstractProductA> <AbstractProductB> <Ab ...

  9. 【python】发送post请求

    1. json格式的post请求 关键部分加粗显示了,主要是post数据的编码方式以及请求头的Content-type #coding=utf8 import json import gzip imp ...

  10. vim 使用技巧记录

    vim 使用技巧记录 1.批量注释与取消注释 命令格式:起始行号,结束行号s#^#//#g 例如: 注释代码3到15行,"//"可以是其他的"" :3,15s# ...