• ReactJS作为目前最火的构建用户界面的前端框架,为什么有那么多的前端工程师...我目前开发的项目,前端UI框架使用的是framework7,ReactJS用来构建用户界面,reflux用来操作数据(主要负责数据请求和数据操作)。 Fram

    ReactJS作为目前最火的构建用户界面的前端框架,为什么有那么多的前端工程师去追逐它,不仅因为它简单,而且它提供了一系列强大的API让我们摆脱以前繁琐的DOM操作,使我们的逻辑更加清晰,代码更加简单。

    一.项目所用的各种框架

    在我目前开发的项目中,前端UI框架使用的是framework7,ReactJS用来构建用户界面,reflux用来操作数据(主要负责数据请求和数据操作)。

    Framework7不仅提供了UI界面,而且还封装了一堆类似jQuery的DOM操作API,而ReactJS是facebook工程师开发的构建用户界面的前端类库,提供了强大的diff算法,在内存中直接操作虚拟DOM,所以Framework7ReactJS结合,有点不伦不类。

    因为我们只需要framework7提供的UI样式,而并不需要它那一堆操作DOM的API,对于没有接触过ReactJS的新同学来说,思维肯定难以转变,可以直接操作DOM那肯定比较爽,react通过state直接更改界面样式的一边玩去吧!所以造成开始进入这项目时,我也是直接操作DOM,所以造成前期代码紊乱,后期维护困难。中途过程中,对于framework7没有的dom操作API,我又引入的Jquery和各种类库。

    而且由于我们项目使用的是spa模式,所以造成后期通过webpack打包的bundle.js多达4M,在低端android机上,加载时间长达几十秒。其实使用react开发的项目完全没必要再引入操作DOM的前端框架,react操作虚拟DOM的性能和速度完全不是直接操作DOM可比的。那样只会造成的应用的卡顿和加载缓慢。

    目前开发的项目中为了仿原生ios效果(如果自己去通过React重新实现的话,成本极大),所以不得不使用Framedmework7来作为前端UI库。

    二.ReactJS简单的介绍

    什么是React?下面是来自React中文文档的说明:

    React 是一个 Facebook 和 Instagram 用来创建用户界面的 JavaScript 库。

    很多人认为 React 是 MVC 中的 V(视图)。

    我们创造 React 是为了解决一个问题:构建随着时间数据不断变化的大规模应用程序。为了达到这个目标,React 采用下面两个主要的思想。

    1:仅仅只要表达出你的应用程序在任一个时间点应该长的样子,然后当底层的数据变了,React 会自动处理所有用户界面的更新

    2:数据变化后,React 概念上与点击“刷新”按钮类似,但仅会更新变化的部分。

    下面谈谈我对React上面两个思想的理解:

    1.React有着极其强大的API,当数据源发生改变,都会触发Render,这也就意味着你只需要关注数据整体,其他的一切React这个框架会去完成,降低了开发的难度和逻辑的复杂程度。

    2.当数据源改变之后,React会在内存中通过diff算法,去比较数据源是否发生更改,在去决定是否更改DOM。因为React有一个非常强大的虚拟DOM系统,所以会在内存中去完成对DOM的所有操作,随后在通过Render函数把对DOM的修改反应到实际DOM中。

    许多人一听,React那么强大,是不是很难?其实非也,React中API少的可怜,非常简单易懂,最常用的也就几个生命周期函数和Render。

    三.React中的生命周期

    1.componentDidMount

    组件已经加载到DOM中会执行这个函数,在这个函数中可以初始化一些将要执行的函数,在React生命周期中只会执行一次。在开发中,在该函数中执行的setState,在随后通过this.state并不能够马上拿到,可以通过定时来获取。

    2.componentWillMount

    在组件将要挂载到DOM中执行,这个函数我基本上很少用到。初始化工作我基本上在constructor和componentDidMount中去完成。

    3.componentWillUnmount

    组件从DOM中移除会执行这个函数,在此可以清理无用的DOM和事件。

    4.componentWillUpdate

    组件将要更新执行。可以在这个函数中清理在componentDidUpdate绑定的事件(这个方式很有用)。

    5.componentDidUpdate

    组件已经更新执行这个操作。可以在这个函数中初始化需要state中的数据源作为参数的函数。为了防止初始化多次,可以在componentWillUpdate中清理。看下面这个需求:

    需要实现一个一元夺宝模块,导航栏下有一个tab栏显示一元夺宝共进行了多少期,当前期数默认第一个tab显示(可滑动)。如下图:


    一元夺宝

    这个使用的是swiper.js来实现的。只能在从服务器获取到期数后实现,所以我们在compoenntDidUpdate中去初始化:


    初始化

    但是我们同时可能又会去获取购物车数量等等进行其他更新state的操作,根据React的生命周期,只要state发生改变,就有可能(shouldComponentUpdate返回true)会去执行componentDidUpdate。这样就会造成这个函数的多次初始化。所以我们必须在componentWillUpdate中去判断把已经初始化的函数进行清理,避免造成多次初始化。


    unmount

    6.shouldComponentUpdate

    这个函数提供给我们这些开发者是否允许数据源发生改变后去执行Render的控制权。默认这个函数始终返回true。返回false的话,render函数不会执行,componentWillUpdate和componentDidUpdate也不会执行。可以在这个函数中去执行逻辑判断,是否有必要去执行Render。为了追求更高的性能。可以手动去控制是否执行Render。

    在开发过程中这些生命周期函数是我使用最频繁最常见的React操作。

    学习React,只要掌握我们只关心数据源,并进行setState,去更新state触发Render就ok了。到此为止,React中的生命周期大致记录到这,以备忘记,进行复习只用。

    React入门并不难,但是深入.....



    文/力谱宿云(简书作者)
    原文链接:http://www.jianshu.com/p/9c26259a817a
    著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
    展开全文
  • 这篇文章主要整理一下自己使用 webpack 结合 vuejs 或 reactjs 开发过程图片的处理方法。 我的需求 项目打包之后(假定输出目录为 dist),除了 index.html,将所有的静态资源上传至 cdn,而并非打包之后所有...

    这篇文章主要整理一下自己在使用 webpack 结合 vuejsreactjs 开发过程中图片的处理方法。

    我的需求

    项目打包之后(假定输出目录为 dist),除了 index.html,将所有的静态资源上传至 cdn,而并非打包之后所有静态资源都在应用服务器上。

    index.html 中的图片

    因为是 SPA,模版页面唯一要处理的图片就是 favicon,这个资源在 IE 10 及以下浏览器只需要在 dist 根目录下存在 favicon.icon 文件(名称、后缀固定)即可,这种方式已经废弃,更好的做法是使用 link 标签引用,如:

    <link rel="icon" sizes="192x192" href="/path/to/icon.png">
    复制代码

    处理这个图片,我尝试了三个方法:

    1.html-webpack-pluginfavicon 属性配置

    不适合我。

    它会将文件输出至 dist 根目录下,与 index.html 同级,引用的是本地图片,而非 cdn 图片。

    2.favicons-webpack-plugin

    不适合我。

    很强大,能根据你给的图片,生成所有类型的 icon 图标,问题有两个:首先是依赖了 phantomjs,墙外的站点,你懂得;再者引用的依旧是本地图片。

    组件实现

    适合我。

    vuejsvue-head 组件,reactjsreact-helmet 组件,可以配置 link 方式的 favicon。图片打包上传 cdn 之后,页面的图片地址也为 cdn 地址。

    其它

    如果你的模版页面有其他诸如 src 图片引用,可参考 html-withimg-loader

    页面 Head 大全

    vuejs 项目中图片处理

    前提:使用 vue-loader v15webpack 配置好 url-loaderalias

    module.exports = {
        // ...其他配置
        modules: {
            rules: [
                {
                    test: /\.(jpe?g|png|gif)(\?.*)?$/,
                    use: 'url-loader?limit=1024&name=statics/img/[name]-[hash:5].[ext]',
                    exclude: /node_modules/,
                },
            ]
        },
        resolve: {
            alias: {
              Images: path.resolve('public', 'statics', 'img'),
            },
        },
        // ...其他配置
    }
    复制代码

    template 中使用

    <img src="~Images/logo.png">
    <img :src="require('Images/logo.png')"> // 注意 v-bind
    复制代码

    有个问题我目前没有解决(精简代码),还请大神指教:

    // 无效,提示无法找到这个资源
    <img :src="require(`${img}`)">
    
    data() {
      img: 'Images/logo.png'
    }
    复制代码
    // 有效
    <img :src="require(`Images/${img}`)">
    
    data() {
      img: 'logo.png'
    }
    复制代码

    已解决,官网对 require 的说明: A context is created if your request contains expressions, so the exact module is not known on compile time.

    样式表中使用

    貌似无法使用 alias,只能使用 ~ 和相对路径:

    body {
      background: url(Images/logo.png); // alias,错误
      background: url(/Images/logo.png); // 有效,但是引用本地文件
      background: url(~Images/logo.png);
      background: url(../../statics/img/logo.png);
      background: url(./../../statics/img/logo.png);
    }
    复制代码

    以 . 开头,将会被看作相对的模块依赖,并按照你的本地文件系统上的目录结构进行解析

    reactjs 中图片处理

    前提:webpack 配置好 url-loaderalias

    使用

    不管是组件中还是样式表中,都可以使用 alias 和相对路径:

    require('Images/logo.png');
    require('../../statics/img/logo.png');
    require('./../../statics/img/logo.png');
    复制代码
    body {
      background: url(Images/logo.png);
      background: url(../../statics/img/logo.png);
      background: url(./../../statics/img/logo.png);
    }
    复制代码

    最后

    ./ 可有可无,相对路径是以当前的文件为基础,注意 ../ 层数问题;不要以 / 开头,因为最终都是引用的本地图片。 如有谬误,恳请斧正。

    转载于:https://juejin.im/post/5b359656e51d4558d9235f1f

    展开全文
  • ReactJS

    2017-03-19 11:08:45
    自从接触了ReactJSReactJs的虚拟DOM(Virtual DOM)和组件化的开发深深的吸引了我,下面来跟我一起领略 ReactJS的风采吧~~ 章有点长,耐心读完,你会有很大收获哦~一、ReactJS简介React 起源于 Facebook 的内部...

    现在最热门的前端框架有AngularJS、React、Bootstrap等。自从接触了ReactJS,ReactJs的虚拟DOM(Virtual DOM)和组件化的开发深深的吸引了我,下面来跟我一起领略
    ReactJS的风采吧~~ 章有点长,耐心读完,你会有很大收获哦~

    一、ReactJS简介

    React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 Instagram 的网站。做出来以后,发现这套东西很好用,就在2013年5月开源了。由于 React 的设计思想极其独特,属于革命性创新,性能出众,代码逻辑却非常简单。所以,越来越多的人开始关注和使用,认为它可能是将来 Web 开发的主流工具。

    ReactJS官网地址:http://facebook.github.io/react/

    Github地址:https://github.com/facebook/react

    二、对ReactJS的认识及ReactJS的优点

    首先,对于React,有一些认识误区,这里先总结一下:

    React不是一个完整的MVC框架,最多可以认为是MVC中的V(View),甚至React并不非常认可MVC开发模式;
    React的服务器端Render能力只能算是一个锦上添花的功能,并不是其核心出发点,事实上React官方站点几乎没有提及其在服务器端的应用;
    有人拿React和Web Component相提并论,但两者并不是完全的竞争关系,你完全可以用React去开发一个真正的Web Component;
    React不是一个新的模板语言,JSX只是一个表象,没有JSX的React也能工作。
    1、ReactJS的背景和原理

    在Web开发中,我们总需要将变化的数据实时反应到UI上,这时就需要对DOM进行操作。而复杂或频繁的DOM操作通常是性能瓶颈产生的原因(如何进行高性能的复杂DOM操作通常是衡量一个前端开发人员技能的重要指标)。React为此引入了虚拟DOM(Virtual DOM)的机制:在浏览器端用Javascript实现了一套DOM API。基于React进行开发时所有的DOM构造都是通过虚拟DOM进行,每当数据变化时,React都会重新构建整个DOM树,然后React将当前整个DOM树和上一次的DOM树进行对比,得到DOM结构的区别,然后仅仅将需要变化的部分进行实际的浏览器DOM更新。而且React能够批处理虚拟DOM的刷新,在一个事件循环(Event Loop)内的两次数据变化会被合并,例如你连续的先将节点内容从A变成B,然后又从B变成A,React会认为UI不发生任何变化,而如果通过手动控制,这种逻辑通常是极其复杂的。尽管每一次都需要构造完整的虚拟DOM树,但是因为虚拟DOM是内存数据,性能是极高的,而对实际DOM进行操作的仅仅是Diff部分,因而能达到提高性能的目的。这样,在保证性能的同时,开发者将不再需要关注某个数据的变化如何更新到一个或多个具体的DOM元素,而只需要关心在任意一个数据状态下,整个界面是如何Render的。

    如果你像在90年代那样写过服务器端Render的纯Web页面那么应该知道,服务器端所要做的就是根据数据Render出HTML送到浏览器端。如果这时因为用户的一个点击需要改变某个状态文字,那么也是通过刷新整个页面来完成的。服务器端并不需要知道是哪一小段HTML发生了变化,而只需要根据数据刷新整个页面。换句话说,任何UI的变化都是通过整体刷新来完成的。而React将这种开发模式以高性能的方式带到了前端,每做一点界面的更新,你都可以认为刷新了整个页面。至于如何进行局部更新以保证性能,则是React框架要完成的事情。

    借用Facebook介绍React的视频中聊天应用的例子,当一条新的消息过来时,传统开发的思路如上图,你的开发过程需要知道哪条数据过来了,如何将新的DOM结点添加到当前DOM树上;而基于React的开发思路如下图,你永远只需要关心数据整体,两次数据之间的UI如何变化,则完全交给框架去做。可以看到,使用React大大降低了逻辑复杂性,意味着开发难度降低,可能产生Bug的机会也更少。

    2、组件化

    虚拟DOM(virtual-dom)不仅带来了简单的UI开发逻辑,同时也带来了组件化开发的思想,所谓组件,即封装起来的具有独立功能的UI部件。React推荐以组件的方式去重新思考UI构成,将UI上每一个功能相对独立的模块定义成组件,然后将小的组件通过组合或者嵌套的方式构成大的组件,最终完成整体UI的构建。例如,Facebook的instagram.com整站都采用了React来开发,整个页面就是一个大的组件,其中包含了嵌套的大量其它组件,大家有兴趣可以看下它背后的代码。

    如果说MVC的思想让你做到视图-数据-控制器的分离,那么组件化的思考方式则是带来了UI功能模块之间的分离。我们通过一个典型的Blog评论界面来看MVC和组件化开发思路的区别。

    对于MVC开发模式来说,开发者将三者定义成不同的类,实现了表现,数据,控制的分离。开发者更多的是从技术的角度来对UI进行拆分,实现松耦合。

    对于React而言,则完全是一个新的思路,开发者从功能的角度出发,将UI分成不同的组件,每个组件都独立封装。

    在React中,你按照界面模块自然划分的方式来组织和编写你的代码,对于评论界面而言,整个UI是一个通过小组件构成的大组件,每个组件只关心自己部分的逻辑,彼此独立。

    072132381261891600.jpg

    React认为一个组件应该具有如下特征:

    (1)可组合(Composeable):一个组件易于和其它组件一起使用,或者嵌套在另一个组件内部。如果一个组件内部创建了另一个组件,那么说父组件拥有(own)它创建的子组件,通过这个特性,一个复杂的UI可以拆分成多个简单的UI组件;

    (2)可重用(Reusable):每个组件都是具有独立功能的,它可以被使用在多个UI场景;

    (3)可维护(Maintainable):每个小的组件仅仅包含自身的逻辑,更容易被理解和维护;

    三、下载ReactJS,编写Hello,world

    ReactJs下载非常简单,为了方便大家下载,这里再一次给出下载地址(链接),下载完成后,我么看到的是一个压缩包。解压后,我们新建一个html文件,引用react.js和JSXTransformer.js这两个js文件。html模板如下(js路径改成自己的):

    QQ截图20150721110651.png

    这里大家可能会奇怪,为什么script的type是text/jsx,这是因为 React 独有的 JSX 语法,跟 JavaScript 不兼容。凡是使用 JSX 的地方,都要加上 type=”text/jsx” 。 其次,React 提供两个库: react.js 和 JSXTransformer.js ,它们必须首先加载。其中,JSXTransformer.js 的作用是将 JSX 语法转为 JavaScript 语法。这一步很消耗时间,实际上线的时候,应该将它放到服务器完成。

    到这里我们就可以开始编写代码了,首先我们先来认识一下ReactJs里面的React.render方法:

    React.render 是 React 的最基本方法,用于将模板转为 HTML 语言,并插入指定的 DOM 节点。

    下面我们在script标签里面编写代码,来输出Hello,world,代码如下:

    QQ截图20150721111143.png

    这里需要注意的是,react并不依赖jQuery,当然我们可以使用jQuery,但是render里面第二个参数必须使用JavaScript原生的getElementByID方法,不能使用jQuery来选取DOM节点。

    然后,在浏览器打开这个页面,就可以看到浏览器显示一个大大的Hello,world,因为我们用了

    标签。
    到这里,恭喜,你已经步入了ReactJS的大门下面,让我们来进一步学习ReactJs吧

    四、Jsx语法

    HTML 语言直接写在 JavaScript 语言之中,不加任何引号,这就是 JSX 的语法,它允许 HTML 与 JavaScript 的混写,了解过AngularJs的看到下面的代码一定会感觉很熟悉的,我们来看代码:

    QQ截图20150721111531.png

    这里我们声明了一个names数组,然后遍历在前面加上Hello,输出到DOM中,输出结果如下:

    QQ截图20150721111639.png

    JSX 允许直接在模板插入 JavaScript 变量。如果这个变量是一个数组,则会展开这个数组的所有成员,代码如下:

    QQ截图20150721111724.png

    显示结果如下:

    QQ截图20150721111738.png

    这里的星号只是做标识用的,大家不要被迷惑了~~

    你看到这里,说明你对React还是蛮感兴趣的,恭喜你,坚持下来了,那么下面,我们开始学习React里面的”真功夫”了~~ Are you ready?

    五、ReactJS组件

    1、组件属性

    前面说了,ReactJS是基于组件化的开发,下面我们开始来学习ReactJS里面的组件,React 允许将代码封装成组件(component),然后像插入普通 HTML 标签一样,在网页中插入这个组件。React.createClass 方法就用于生成一个组件类。

    下面,我们来编写第一个组件Greet,有一个name属性,然后输出hello + name的值,代码如下:

    QQ截图20150721111858.png

    看到这段代码,接触过AngularJS的朋友们是不是有一种熟悉的感觉,不过这里有几点需要注意:

    1)获取属性的值用的是this.props.属性名

    2)创建的组件名称首字母必须大写。

    3)为元素添加css的class时,要用className。

    4)组件的style属性的设置方式也值得注意,要写成style={{width: this.state.witdh}}。

    2、组件状态

    组件免不了要与用户互动,React 的一大创新,就是将组件看成是一个状态机,一开始有一个初始状态,然后用户互动,导致状态变化,从而触发重新渲染 UI 。下面我们来编写一个小例子,一个文本框和一个button,通过点击button可以改变文本框的编辑状态,禁止编辑和允许编辑。通过这个例子来理解ReactJS的状态机制。先看代码:

    QQ截图20150721112014.png

    这里,我们又使用到了一个方法getInitialState,这个函数在组件初始化的时候执行,必需返回NULL或者一个对象。这里我们可以通过this.state.属性名来访问属性值,这里我们将enable这个值跟input的disabled绑定,当要修改这个属性值时,要使用setState方法。我们声明handleClick方法,来绑定到button上面,实现改变state.enable的值。效果如下:

    072305421429007.gif

    原理分析:

    当用户点击组件,导致状态变化,this.setState 方法就修改状态值,每次修改以后,自动调用 this.render 方法,再次渲染组件。

    这里值得注意的几点如下:

    1)getInitialState函数必须有返回值,可以是NULL或者一个对象。

    2)访问state的方法是this.state.属性名。

    3)变量用{}包裹,不需要再加双引号。

    3、组件的生命周期

    组件的生命周期分成三个状态:

    Mounting:已插入真实 DOM
    Updating:正在被重新渲染
    Unmounting:已移出真实 DOM
    React 为每个状态都提供了两种处理函数,will 函数在进入状态之前调用,did 函数在进入状态之后调用,三种状态共计五种处理函数。

    componentWillMount()
    componentDidMount()
    componentWillUpdate(object nextProps, object nextState)
    componentDidUpdate(object prevProps, object prevState)
    componentWillUnmount()
    此外,React 还提供两种特殊状态的处理函数。

    componentWillReceiveProps(object nextProps):已加载组件收到新的参数时调用
    shouldComponentUpdate(object nextProps, object nextState):组件判断是否重新渲染时调用
    下面来看一个例子:

    QQ截图20150721112254.png

    上面代码在hello组件加载以后,通过 componentDidMount 方法设置一个定时器,每隔100毫秒,就重新设置组件的透明度,从而引发重新渲染。

    4、组件的嵌套

    React是基于组件化的开发,那么组件化开发最大的优点是什么?毫无疑问,当然是复用,下面我们来看看React中到底是如何实现组件的复用的,这里我们还写一个例子来说吧,代码如下:

    QQ截图20150721112325.png

    这里我们创建了一个Search组件,然后又创建了一个Page组件,然后我们在Page组件中调用Search组件,并且调用了两次,这里我们通过属性searchType传入值,最终显示结果如图:

    六、ReactJS小结

    关于ReactJS今天就先学习到这里了,下面来总结一下,主要有以下几点:

    1、ReactJs是基于组件化的开发,所以最终你的页面应该是由若干个小组件组成的大组件。

    2、可以通过属性,将值传递到组件内部,同理也可以通过属性将内部的结果传递到父级组件(留给大家研究);要对某些值的变化做DOM操作的,要把这些值放到state中。

    3、为组件添加外部css样式时,类名应该写成className而不是class;添加内部样式时,应该是style={{opacity: this.state.opacity}}而不是style=”opacity:{this.state.opacity};”。

    4、组件名称首字母必须大写。

    5、变量名用{}包裹,且不能加双引号。

    展开全文
  • React最重要的就是组件了,组件之间可以嵌套使用,那么,父组件和子组件之间,如何进行通信呢? 下面用一个例子记录React组件之间的通信,因为组件包含有属性和状态两个对象,所以组件间的通信,主要通过这两...

    React中最重要的就是组件了,组件之间可以嵌套使用,那么,父组件和子组件之间,如何进行通信呢?

    下面用一个例子记录React中组件之间的通信,因为组件中包含有属性和状态两个对象,所以组件间的通信,主要通过这两个对象来完成。

    父组件给子组件通信,可以直接使用props,让父组件传递给子组件一个属性,子组件拿到这个属性即可;

    子组件给父组件通信,也需要用到props,不过这个就有点类似于回调函数了,即父组件传给子组件一个函数,这个函数存在于父组件中,子组件通过回调这个函数,来让父组件做相应的操作,下面是一个父子组件互相通信的Demo,在浏览器中运行的效果如下图:


    在父组件的输入框中输入内容后,该内容会同步显示到子组件中,或者在子组件的输入框中输入内容,该内容会同步显示到父组件中,如下图所示:


    下面贴上这个Demo的代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>组件的嵌套和通信</title>
    	<!-- 引入React需要用到的js文件 -->
    	<script type="text/javascript" src="../react-0.13.0/build/react.js"></script>
    	<script type="text/javascript" src="../react-0.13.0/build/JSXTransformer.js"></script>
    	<!-- 这里是组件用到的css样式 -->
    	<style type="text/css">
    		.parentComponent {
    			width: 400px;
    			height: 500px;
    			border-style: solid;
    			border-width: 1px;
    			background-color: #6699ff;
    		}
    		.childComponent {
    			width: 350px;
    			height: 300px;
    			margin-left: 25px;
    			border-style: solid;
    			border-width: 1px;
    			background-color: #00aaaa;
    		}
    		.title {
    			padding: 10px 0px 10px 0px
    		}
    	</style>
    </head>
    <body>
    	<div id="container"></div>
    	<script type="text/jsx">
    		//定义父组件
    		var ParentComponent = React.createClass({
    			getInitialState: function() {
    				return {
    					parentInput: '',                 //父组件的输入框中的内容
    					childInput: '', 			     //子组件的输入框中的内容
    					onChange: this.handleChange      //传给子组件,用于监听子组件输入框内容改变的函数 
    				};
    			},
    			//处理父组件和子组件的输入框内容改变的事件,isParent用于区分是父组件还是子组件
    			handleChange: function(isParent, event) {
    				if(isParent) {
    					//是父组件输入框内容发生变化,则修改state,让子组件的输入框跟着改变,注意state的改变,会导致组件重新渲染
    					this.setState({parentInput: event.target.value});
    				}else{
    					//是子组件输入框,则修改state,让父组件的输入框跟着改变
    					this.setState({childInput: event.target.value});
    				}
    			},
    			render: function() {
    				return (
    					<div className="parentComponent">
    						<div className="title" style={{width: '400px', backgroundColor: '#ececec'}}>我是父组件</div>
    						<br/>
    						<input type="text" onChange={this.handleChange.bind(this, true)} style={{width: '350px', height: '30px', marginLeft: '25px'}} placeholder="在这里输入的文本,将显示到子组件中"/>
    						<br/><br/>
    						<input type="text" disabled="disabled" value={this.state.childInput} style={{width: '350px', height: '30px', marginLeft: '25px'}} placeholder="子组件中输入的文本,将显示在这里"/>
    						<br/><br/>
    						<ChildComponent data={this.state}/> 
    					</div>
    				);
    			}
    		});
    		//定义子组件
    		var ChildComponent = React.createClass({
    			render: function() {
    				return (
    					<div className="childComponent">
    						<div className="title" style={{width: '350px', backgroundColor: '#ececec'}}>我是子组件</div>
    						<br/>
    						<input type="text" disabled="disabled" style={{width: '300px', height: '30px', marginLeft: '25px'}} placeholder="父组件中输入的内容,将显示在这里" value={this.props.data.parentInput}/>
    						<br/><br/>
    						<input type="text" onChange={this.props.data.onChange.bind(this, false)} style={{width: '300px', height: '30px', marginLeft: '25px'}} placeholder="在这里输入的文本,将显示到父组件中"/>
    						<br/><br/>
    					</div>
    				);
    			}
    		});
    		React.render(<ParentComponent />,
    			document.getElementById('container'));
    	</script>
    </body>
    </html>


    展开全文
  • 问题一:ReactJS组件难以复杂交互页面复用 ReactJS中的最小复用单位是组件。ReactJS的组件比AngularJS的Controller和View 要轻量些。每个组件只需要前端开发者提供一个 render 函数,把 props 和 state 映射...

    问题一:ReactJS组件难以在复杂交互页面中复用

    ReactJS中的最小复用单位是组件。ReactJS的组件比AngularJS的Controller和View 要轻量些。每个组件只需要前端开发者提供一个 render 函数,把 props 和 state 映射成网页元素。

    这样的轻量级组件在渲染简单静态页面时很好用,但是如果页面有交互,就必须在组件间传递回调函数来处理事件。尤其是复杂的网页结构,往往需要多个组件层层嵌套,导致回调函数也必须在父子组件间层层传递,代码变成一团乱麻,维护就很难了。

    我将在《More than React(二)组件对复用性有害?》中用原生DHTML API、ReactJS和Binding.scala实现同一个需要复用的页面,介绍Binding.scala如何简单实现、简单复用复杂的交互逻辑。

    问题二:ReactJS的虚拟DOM 算法又慢又不准

    ReactJS的页面渲染算法是虚拟DOM差量算法。

    开发者需要提供 render 函数,根据 props 和 state 生成虚拟 DOM。然后 ReactJS 框架根据 render 返回的虚拟 DOM 创建相同结构的真实 DOM.

    每当 state 更改时,ReacJS 框架重新调用 render 函数,获取新的虚拟 DOM 。然后,框架会比较上次生成的虚拟 DOM 和新的虚拟 DOM 有哪些差异,然后把差异应用到真实DOM上。

    这样做有两大缺点:

    1. 每次 state 更改,render 函数都要生成完整的虚拟 DOM. 哪怕 state 改动很小,render函数也会完整计算一遍。如果 render 函数很复杂,这个过程就白白浪费了很多计算资源。
    2. ReactJS框架比较虚拟DOM差异的过程,既慢又容易出错。比如,假如你想要在某个 <ul> 列表的顶部插入一项<li> ,那么ReactJS框架会误以为你修改了 <ul> 的每一项 <li>,然后在尾部插入了一个 <li>。

    这是因为 ReactJS收到的新旧两个虚拟DOM之间相互独立,ReactJS并不知道数据源发生了什么操作,只能根据新旧两个虚拟DOM来猜测需要执行的操作。自动的猜测算法既不准又慢,必须要前端开发者手动提供 key 属性、shouldComponentUpdate 方法、componentDidUpdate 方法或者 componentWillUpdate 等方法才能帮助 ReactJS 框架猜对。

    我将在《More than React(三)虚拟DOM已死?》中比较ReactJS、AngularJS和Binding.scala渲染机制,介绍简单性能高的Binding.scala精确数据绑定机制。

    问题三:ReactJS的HTML模板功能既不完备、也不健壮

    ReactJS支持用JSX编写HTML模板。

    理论上,前端工程师只要把静态HTML原型复制到JSX源文件中,增加一些变量替换代码,就能改造成动态页面。理论上这种做法要比Cycle.js、Widok、ScalaTags等框架更适合复用设计师提供的HTML原型。

    不幸的是,ReactJS对HTML的支持残缺不全。开发者必须手动把class和for属性替换成className和htmlFor,还要把内联的style样式从CSS语法改成JSON语法,代码才能运行。这种开发方式下,前端工程师虽然可以把HTML原型复制粘贴到代码中,但还需要大量改造才能实际运行。比Cycle.js、Widok、或者、ScalaTags省不了太多事。

    除此之外,ReactJS还提供了propTypes机制校验虚拟DOM的合法性。然而,这一机制也漏洞百出。即使指定了propTypes,ReactJS也不能在编译前提前发现错误。只有测试覆盖率很高的项目时才能在每个组件使用其他组件时进行校验。即使测试覆盖率很高,propTypes仍旧不能检测出拼错的属性名,如果你把onClick写成了onclick,ReactJS就不会报错,往往导致开发者额外花费大量时间排查一个很简单的bug。

    我将在《More than React(四)HTML也可以静态编译?》中比较ReactJS和Binding.scala的HTML模板,介绍Binding.scala如何在完整支持XHTML语法的同时静态检查语法错误和语义错误。

    问题四:ReactJS与服务器通信时需要复杂的异步编程

    ReactJS从服务器加载数据时的架构可以看成MVVM(Model–View–ViewModel)模式。前端工程师需要编写一个服务访问层作为Model,把ReactJS的state当做ViewModel,而render当做View。Model负责访问后端API并把数据设置到state(即View Model)上,可以用Promise和fetch API实现。然后,render,即View,负责把View Model渲染到页面上。

    在这整套流程中,前端程序员需要编写大量闭包组成的异步流程,设置、访问状态的代码五零四散,一不小心就会bug丛生,就算小心翼翼的处理各种异步事件,也会导致程序变得复杂,既难调试,又难维护。

    我将在《More than React(五)为什么别用异步编程?》中比较ReactJS和Binding.scala的数据同步模型,介绍Binding.scala如何自动同步服务器数据,避免手动异步编程。

    结论

    尽管Binding.scala初看上去很像ReactJS,但隐藏在Binding.scala背后的机制更简单、更通用,与ReactJS和Widok截然不同。

    所以,通过简化概念,Binding.scala灵活性更强,能用通用的方式解决ReactJS解决不了的复杂问题。

    展开全文
  • 自从接触了ReactJSReactJs的虚拟DOM(Virtual DOM)和组件化的开发深深的吸引了我,下面来跟我一起领略 ReactJS的风采吧~~ 章有点长,耐心读完,你会有很大收获哦~ 一、ReactJS简介 React 起源于 Facebook ...
  • ReactJS好文分享
  • ReactJs入门教程

    2017-08-22 11:42:22
    自从接触了ReactJSReactJs的虚拟DOM(Virtual DOM)和组件化的开发深深的吸引了我,下面来跟我一起领略 ReactJS的风采吧~~ 章有点长,耐心读完,你会有很大收获哦~ 一、ReactJS简介 react 起源于 ...
  • ReactJS 知识简介

    2015-09-20 14:23:20
    自从接触了ReactJSReactJs的虚拟DOM(Virtual DOM)和组件化的开发  一、ReactJS简介  React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,...
  • 一看就懂的ReactJs教程

    2016-09-11 15:43:06
    自从接触了ReactJSReactJs的虚拟DOM(Virtual DOM)和组件化的开发深深的吸引了我,下面来跟我一起领略 ReactJS的风采吧~~ 章有点长,耐心读完,你会有很大收获哦~ 一、ReactJS简介 React 起源于 Facebook 的...
  • 《More than React》系列的文章会一共分为五篇和一则附录。本文是第一篇,介绍用 ReactJS开发时遇到的种种问题。...\\背景介绍\\去年 4 月,我第一次某个客户的项目接触到ReactJS 。\\我发现ReactJS要...
  • 介绍 Facebook内部的项目 2013年5月份开源 代码逻辑简单,性能出众 前端三大框架 AngularJs 学习曲线比较陡 ng1较难 ng2之后简单 也支持使用TS进行... ReactJs 最流行的一门框架,因为设计的很优秀 React和Vu...
  • Reactjs 入门实例教程

    2016-07-30 20:31:51
    现在最热门的前端框架,毫无疑问是 React 。 上周,基于 React 的 React Native 发布,结果一天之内,就获得了 5000 颗星,受瞩目程度可见一斑。...React 起源于 Facebook 的内部项目,因为该公司对市场上...
  • 介绍  1,React Js的目的 是为了使前端的V层更具...2,React Native的目的 是希望我们能够使用前端的技术栈就可以创建出能够不同平台运行的一个框架。可以创建出移动端运行的app,但是性能可能比原声app差一点。
  • 《More than React》系列的文章会一共分为五篇。本文是第一篇,介绍用...去年 4 月,我第一次某个客户的项目接触到ReactJS 。 我发现ReactJS要比我以前用过的AngularJS简单很多,它提供了响应式的数据绑定功
1 2 3 4 5 ... 20
收藏数 1,610
精华内容 644
热门标签