欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

超級給力的JavaScript的React框架入門教程

 更新時間:2015年07月02日 11:13:43   投稿:goldensun  
這篇文章主要介紹了JavaScript的React框架入門教程,目前React框架正被Facebook開源極力推廣中,此文強烈推薦!需要的朋友可以參考下

 React 是 Facebook 里一群牛 X 的碼農(nóng)折騰出的牛X的框架。 實現(xiàn)了一個虛擬 DOM,用 DOM 的方式將需要的組件秒加,用不著的秒刪。React 扮演著 MVC 結(jié)構(gòu)中 V 的角色, 不過你要是 Flux 搭配使用, 你就有一個很牛X的能讓輕松讓 M 和 V 同步的框架了,F(xiàn)lux 的事以后再說~
組件們

在 React 中,你可以創(chuàng)建一個有特殊功能的組件,這在 HTML 元素里你是打著燈籠也找不到的,比如這個教程里的下拉導(dǎo)航。每個組件都有自己的地盤(scope),所以我們定義一個組件后可以反復(fù)的用反復(fù)的用,根本就不需要和別的組件交互!

每個組件都有一個功能叫 render , 它可以高效的返回要射到瀏覽器上 HTML。我們也可以調(diào)用 React 的其他組件,這意味這一入 React 深似海,哦,不對,是只有想不到,沒有做不到。

JSX

如果你經(jīng)常注意React你也許會發(fā)現(xiàn)有個東西叫JSX。JSX允許我們在Javascript中寫HTML,而不是用HTML包含Javascript。它能幫助我們快速開發(fā),因為我們不用擔(dān)心字符串和換行等。你可以在瀏覽器中運行JSX,但是不推薦,因為這樣會減慢你的頁面速度。gulp和grunt為你的預(yù)處理任務(wù)提供了一個JSX解釋器,所以如果你想使用JSX,我建議開啟這個功能。
使用 JSX

如前面所說,JSX每一個組件都有一個 render 方法,這個方法產(chǎn)生一個"ViewModel(視圖模型)" - 在返回HTML到組件之前,你可以將這個模型(ViewModel)的信息放入視圖中,意味著你的HTML會根據(jù)這個模型動態(tài)改變(例如一個動態(tài)列表)。


一旦你完成了操作,就可以返回你想渲染(render)的東西,我們使用JSX來做是如此簡單
 

var ExampleComponent = React.createClass({
  render: function () {
    return (
      <div className="navigation">
        Hello World!
      </div>
      );
  }
});

如果你要在你的瀏覽器中運行這段代碼,只會得到語法錯誤的提示,因為在Javascript中<和>字符要用引號包含起來。當(dāng)你在代碼上運行JSX解釋器,它將被轉(zhuǎn)換成這樣
 

var ExampleComponent = React.createClass({
  render: function () {
    return (
      React.createElement('div', {className: 'navigation'}, 'Hello World!')
      );
  }
});

可以點此測試示例 - 我使用的是瀏覽器JSX解釋器(這并不推薦,但是為了JSFiddle)。

運行了!JSX解釋了你使用 React.createElement 生成的所有DOM節(jié)點,生成了節(jié)點類型、參數(shù)和內(nèi)容。你可以不用JSX,但這意味著你必須要手動寫 React.createElement 以外的所有DOM節(jié)點。無數(shù)例子告訴我要使用JSX。

你一定很疑惑我為什么在DOM上使用 className 來代替 class。這是因為 class 是Javascript的保留詞。當(dāng)JSX解釋你的代碼時就會改變這節(jié)點上的所有屬性到一個對象上,但你不能把對象當(dāng)作屬性!

將變量用在屬性上
如果你想動態(tài)改變組件的樣式類(或者任何其他的屬性值),你可以使用變量. 不過你不能只是傳進去一個變量名稱,你還要將其用一對大括弧包起來, 這樣JSX就能知道這是一個外部的變量了.
 

var ExampleComponent = React.createClass({
render: function () {
  var navigationClass = 'navigation';
  return (
    <div className={ navigationClass }>
      Hello World!
    </div>
    );
}
});

你可以在這兒看到這個功能.
初始的渲染器
當(dāng)你最開始要渲染一個React組件時,你需要告訴React是要渲染什么組件,還要制定一個現(xiàn)有的DOM節(jié)點以表示在哪兒渲染這個組件. 為此你會要使用React.render函數(shù).
 

var ExampleComponent = React.createClass({
render: function () {
  return (
    <div className="navigation">
      Hello World!
    </div>
    );
}
});
React.render(<ExampleContent />, document.body);

他將會在body節(jié)點上渲染組件——簡單吧! 從此你就可以像通常那樣調(diào)用其他的組件了, 或者如果你希望的話,可以使用render函數(shù)許多次, 如果你不想使用React來渲染整個頁面,但仍然想要使用多個組件.

一個組件的基礎(chǔ)

組件可以擁有其自己的“狀態(tài)”。這使我們能夠重復(fù)多次使用相同的組件但卻讓它們看起來完全不同,因為每個組件實例的狀態(tài)是唯一的。

當(dāng)你通過傳遞屬性到一個組件時這些被稱為屬性。不要只局限于 HTML 屬性,你可以傳遞任何你想傳遞的東西,并在組件內(nèi)通過 this.props 訪問它。這樣使得我們能夠重復(fù)使用相同的組件但傳遞一組不同的屬性,比如組件的“配置”。
屬性

根據(jù)我們前面“Hello World!”的例子,我們在 HTML 節(jié)點上有 className 的屬性。在組件內(nèi)部,我們可以使用 this.props.classname 訪問這個值,但正如前面所述,你可以傳遞任何你喜歡的內(nèi)容。對我們的下拉來說,我們需要將導(dǎo)航配置為對象,組件將使用它作為要渲染的配置。讓我們開始吧—
 

var navigationConfig = [];
 
var Navigation = React.createClass({
  render: function () {
    return (
      <div className="navigation">
         
      </div>
      );
  }
});

 
React.render(<Navigation config={ navigationConfig } />, document.body);

如果現(xiàn)在能訪問 this.props.config 的話,我們會受到一個空數(shù)組(navigationConfig 的值)。在我們進入到真正導(dǎo)航的編碼前先讓我們說明一下狀態(tài)。

狀態(tài)

如之前所討論的,每一個組件都有其自己的”狀態(tài)”。當(dāng)要使用狀態(tài)時,你要定義初始狀態(tài),讓后才可以使用 this.setState 來更新狀態(tài)。無論何時狀態(tài)得到了更新,組件都會再一次調(diào)用 render 函數(shù),拿新的值去替換或者改變之前渲染的值。這就是虛擬 DOM 的奧義 - 計算差異的算法實在 React 內(nèi)部完成的,因此我們不用去以來 DOM 的更新了(因為 DOM 很慢)。React 會計算出差異并產(chǎn)生一堆指令的集合 (例如,加入向”navigation__link“加入”active“類,或者移除一個節(jié)點),并在 DOM 上執(zhí)行它們。

使用導(dǎo)航,我們將下拉菜單打開保持在狀態(tài)中。為此,添加一個 getInitialState 函數(shù)到類配置對象上,并返回帶有我們想要的初始狀態(tài)的對象。
 

var navigationConfig = [];
 
var Navigation = React.createClass({
  getInitialState: function () {
    return {
      openDropdown: -1
    };
  },
  render: function () {
    return (
      <div className="navigation">
         
      </div>
      );
  }
});
 
React.render(<Navigation config={ navigationConfig } />, document.body);

你會發(fā)現(xiàn)我們將其設(shè)置成了-1。當(dāng)我們準(zhǔn)備去打開一個下拉菜單時,將使用狀態(tài)里面的配置數(shù)組中的導(dǎo)航項的位置,而由于數(shù)組索引開始于0,我們就得使用 -1 來表示還沒有指向一個導(dǎo)航項。

我們可以使用 this.state 來訪問狀態(tài),因此如果我們?nèi)ビ^察 atthis.state.openDropdown,應(yīng)該會有 -1 被返回。

組件的生命周期

每個組件都有其“生命周期”—這是一系列你可以在組件配置里定義的函數(shù),它們將在部件生命周期內(nèi)被調(diào)用。我們已經(jīng)看過了 getinitialstate 一它只被調(diào)用一次,在組件被掛載時調(diào)用。
componentWillMount

當(dāng)組件要被掛載時這個函數(shù)被調(diào)用。這意味著我們可以在此運行組件功能必須的代碼。為由于 render 在組件生命周期里被多次調(diào)用,我們一般會把只需要執(zhí)行一次的代碼放在這里,比如 XHR 請求。
 

var ExampleComponent = React.createClass({
  componentWillMount: function () {
    // xhr request here to get data
  },
  render: function () {
    // this gets called many times in a components life
    return (
      <div>
        Hello World!
      </div>
      );
  }
});

componentDidMount

一旦你的組件已經(jīng)運行了 render 函數(shù),并實際將組件渲染到了 DOM 中,componentDidMount 就會被調(diào)用。我們可以在這兒做任何需要做的 DOM 操作,已經(jīng)任何需要依賴于組件已經(jīng)實際存在于 DOM 之后才能做的事情, 例如渲染一個圖表。你可以通過調(diào)用 this.getDOMNode 在內(nèi)部訪問到 DOM 節(jié)點。
 

var ExampleComponent = React.createClass({
  componentDidMount: function () {
    var node = this.getDOMNode();
    // render a chart on the DOM node
  },
  render: function () {
    return (
      <div>
        Hello World!
      </div>
      );
  }
});

componentWillUnmount

如果你準(zhǔn)備吧組件從 DOM 移除時,這個函數(shù)將會被調(diào)用。這讓我們可以在組件背后進行清理,比如移除任何我們已經(jīng)綁定的事件監(jiān)聽器。如果我們沒有在自身背后做清理,而當(dāng)其中一個事件被觸發(fā)時,就會嘗試去計算一個沒有載入的組件,React 就會拋出一個錯誤。
 

var ExampleComponent = React.createClass({
  componentWillUnmount: function () {
    // unbind any event listeners specific to this component
  },
  render: function () {
    return (
      <div>
        Hello World!
      </div>
      );
  }
});

組件方法

React 也為組件提供了更方便我們工作的方法。它們會在組件的創(chuàng)建過程中被調(diào)用到。例如getInitialState,能讓我們定義一個默認(rèn)的狀態(tài),這樣我們不用擔(dān)心在代碼里面對狀態(tài)項目是否存在做進一步的檢查了。
getDefaultProps

當(dāng)我們創(chuàng)建組件時,可以按照我們的想法為組件的屬性定義默認(rèn)值。這意味著我們在調(diào)用組件時,如果給這些屬性設(shè)置值,組件會有一個默認(rèn)的“配置”,而我們就不用操心在下一行代碼中檢查屬性這類事情了。

當(dāng)你定義了組件時,這些默認(rèn)的屬性會被緩存起來,因而針對每個組件的實例它們都是一樣的,并且不能被改變。對于導(dǎo)航組件,我們將配置指定為一個空的數(shù)組,因而就算沒有傳入配置,render 方法內(nèi)也不會發(fā)生錯誤。
 

var Navigation = React.createClass({
  getInitialState: function () {
    return {
      openDropdown: -1
    };
  },
  getDefaultProps: function () {
    return {
      config: []
    }
  },
  render: function () {
    return (
      <div className="navigation">
         
      </div>
      );
  }
});

React.render(<Navigation config={ navigationConfig } />, document.body);

propTypes

我們也可以隨意為每一個屬性指定類型。這對于我們檢查和處理屬性的意外賦值非常有用。如下面的dropdown,我們指定只有數(shù)組才能放入配置。
 

var Navigation = React.createClass({
  getInitialState: function () {
    return {
      openDropdown: -1
    };
  },
  getDefaultProps: function () {
    return {
      config: []
    }
  },
  propTypes: {
    config: React.PropTypes.array
  },
  render: function () {
    return (
      <div className="navigation">
         
      </div>
      );
  }
});
 
React.render(<Navigation config={ navigationConfig } />, document.body);

mixins

我們也可以在組件中加入 mixins。這是一個獨立于 React 的基本組件(只是一個對象類型的配置)。這意味著,如果我們有兩個功能類似的組件,就可以共享一個配置了(如果初始狀態(tài)相同)。我們可以抽象化地在 mixin 中建立一個方法,這樣就不用把相同的代碼寫上兩次了。
 

var ExampleMixin = {
  componentDidMount: function () {
    // bind some event listeners here
  },
  componentWillUnmount: function () {
    // unbind those events here!
  }
};
 
var ExampleComponent = React.createClass({
  mixins: [ExampleMixin],
  render: function () {
    return (
      <div>
        Hello World!
      </div>
      );
  }
});
 
var AnotherComponent = React.createClass({
  mixins: [ExampleMixin],
  render: function () {
    return (
      <div>
        Hello World!
      </div>
      );
  }
});

這樣全部組件都有一樣的 componentDidMount 和 componentWillUnmount 方法了,保存我們重寫的代碼。無論如何,你不能 override(覆蓋)這些屬性,如果這個屬性是在mixin里設(shè)置的,它在這個組件中是不可覆蓋的。

遍歷循環(huán)

當(dāng)我們有一個包含對象的數(shù)組,如何循環(huán)這個數(shù)組并渲染每一個對象到列表項中?JSX 允許你在任意 Javascript 文件中使用它,你可以映射這個數(shù)組并返回 JSX,然后使用 React 去渲染。
 

var navigationConfig = [
  {
    href: 'http://ryanclark.me',
    text: 'My Website'
  }
];
var Navigation = React.createClass({
  getInitialState: function () {
    return {
      openDropdown: -1
    };
  },
  getDefaultProps: function () {
    return {
      config: []
    }
  },
  propTypes: {
    config: React.PropTypes.array
  },
  render: function () {
    var config = this.props.config;
    var items = config.map(function (item) {
      return (
        <li className="navigation__item">
          <a className="navigation__link" href={ item.href }>
            { item.text }
          </a>
        </li>
        );
    });
    return (
      <div className="navigation">
        { items }
      </div>
      );
  }
});
React.render(<Navigation config={ navigationConfig } />, document.body);

在 JSFilddle 中隨意使用 navigationConfigin

導(dǎo)航配置由數(shù)組和對象組成,包括一個指向超鏈接的 href 屬性和一個用于顯示的 text 屬性。當(dāng)我們映射的時候,它會一個個依次通過這個數(shù)組去取得對象。我們可以訪問 href 和 text,并在 HTML 中使用。當(dāng)返回列表時,這個數(shù)組里的列表項都將被替換,所以我們把它放入 React 中處理時它將知道怎么去渲染了!

混編

到目前位置,我們已經(jīng)做到了所有下拉列表的展開。我們需要知道被下來的項目是哪個,我們將使用 .children 屬性去遍歷我們的 navigationConfig 數(shù)組。接下來,我們可以通過循環(huán)來操作下拉的子元素條目。

var navigationConfig = [
  {
    href: 'http://ryanclark.me',
    text: 'My Website',
    children: [
      {
        href: 'http://ryanclark.me/how-angularjs-implements-dirty-checking/',
        text: 'Angular Dirty Checking'
      },
      {
        href: 'http://ryanclark.me/getting-started-with-react/',
        text: 'React'
      }
    ]
  }
];
var Navigation = React.createClass({
  getInitialState: function () {
    return {
      openDropdown: -1
    };
  },
  getDefaultProps: function () {
    return {
      config: []
    }
  },
  propTypes: {
    config: React.PropTypes.array
  },
  render: function () {
    var config = this.props.config;
    var items = config.map(function (item) {
      var children, dropdown;
      if (item.children) {
        children = item.children.map(function (child) {
          return (
            <li className="navigation__dropdown__item">
              <a className="navigation__dropdown__link" href={ child.href }>
                { child.text }
              </a>
            </li>
          );
        });
        dropdown = (
          <ul className="navigation__dropdown">
            { children }
          </ul>
        );
      }
      return (
        <li className="navigation__item">
          <a className="navigation__link" href={ item.href }>
            { item.text }
          </a>
          { dropdown }
        </li>
        );
    });
    return (
      <div className="navigation">
        { items }
      </div>
      );
  }
});
React.render(<Navigation config={ navigationConfig } />, document.body);

實例在這里 - 但是我們還是能看見下來條目,盡管我們將 openDropdown 設(shè)置成為了 -1 。

我們可以通過在組件中訪問 this.state ,來判斷下拉是否被打開了,并且,我們可以為其添加一個新的 css 樣式 class 來展現(xiàn)鼠標(biāo) hover 的效果。
 

var navigationConfig = [
  {
    href: 'http://ryanclark.me',
    text: 'My Website',
    children: [
      {
        href: 'http://ryanclark.me/how-angularjs-implements-dirty-checking/',
        text: 'Angular Dirty Checking'
      },
      {
        href: 'http://ryanclark.me/getting-started-with-react/',
        text: 'React'
      }
    ]
  }
];
var Navigation = React.createClass({
  getInitialState: function () {
    return {
      openDropdown: -1
    };
  },
  getDefaultProps: function () {
    return {
      config: []
    }
  },
  openDropdown: function (id) {
    this.setState({
      openDropdown: id
    });
  },
  closeDropdown: function () {
    this.setState({
      openDropdown: -1
    });
  },
  propTypes: {
    config: React.PropTypes.array
  },
  render: function () {
    var config = this.props.config;
    var items = config.map(function (item, index) {
      var children, dropdown;
      if (item.children) {
        children = item.children.map(function (child) {
          return (
            <li className="navigation__dropdown__item">
              <a className="navigation__dropdown__link" href={ child.href }>
                { child.text }
              </a>
            </li>
          );
        });
        var dropdownClass = 'navigation__dropdown';
        if (this.state.openDropdown === index) {
          dropdownClass += ' navigation__dropdown--open';
        }
        console.log(this.state.openDropdown, index);
        dropdown = (
          <ul className={ dropdownClass }>
            { children }
          </ul>
        );
      }
      return (
        <li className="navigation__item" onMouseOut={ this.closeDropdown } onMouseOver={ this.openDropdown.bind(this, index) }>
          <a className="navigation__link" href={ item.href }>
            { item.text }
          </a>
          { dropdown }
        </li>
        );
    }, this);
    return (
      <div className="navigation">
        { items }
      </div>
      );
  }
});
React.render(<Navigation config={ navigationConfig } />, document.body);

在這里看實例 - 鼠標(biāo)劃過“My Website”,下拉即會展現(xiàn)。


在前面,我已經(jīng)給每個列表項添加了鼠標(biāo)事件。如你所見,我用的是 .bind (綁定) 調(diào)用,而非其它的方式調(diào)用 - 這是因為,當(dāng)用戶的鼠標(biāo)劃出元素區(qū)域,我們并不用關(guān)注光標(biāo)在哪里,所有我們需要知曉的是,將下拉關(guān)閉掉,所以我們可以將它的值設(shè)置成為-1。但是,我們需要知曉的是當(dāng)用戶鼠標(biāo)劃入的時候哪個元素被下拉展開了,所以我們需要知道該參數(shù)(元素的索引)。 我們使用綁定的方式去調(diào)用而非簡單的透過函數(shù)(function)去調(diào)用是因為我們需要通過 React 去調(diào)用。如果我們直接調(diào)用,那我們就需要一直調(diào)用,而不是在事件中調(diào)用他。

現(xiàn)在我們可以添加很多的條目到 navigationConfig 當(dāng)中,而且我們也可以給他添加樣式到下來功能當(dāng)中。查看實例.

相關(guān)文章

  • Javascript核心讀書有感之語言核心

    Javascript核心讀書有感之語言核心

    本節(jié)是javascript語言的一個快速預(yù)覽,也是本書的第一部分快速預(yù)覽。有想閱讀此書的小伙伴,建議先讀下本系列文章。
    2015-02-02
  • js的匿名函數(shù)使用介紹

    js的匿名函數(shù)使用介紹

    匿名函數(shù)的作用是創(chuàng)建一塊封閉區(qū)域,外面不能夠訪問里面的變量和方法,下面為大家介紹下什么是匿名函數(shù)及其如何使用
    2013-12-12
  • JS創(chuàng)建類和對象的兩種不同方式

    JS創(chuàng)建類和對象的兩種不同方式

    定義了一個新的函數(shù), 你實際上聲明了一個新的類, 而這個函數(shù)本身就相當(dāng)于類的構(gòu)造函數(shù),下面為大家展示創(chuàng)建一個新類的兩種不同方式
    2014-08-08
  • Underscore.js 1.3.3 中文注釋翻譯說明

    Underscore.js 1.3.3 中文注釋翻譯說明

    Underscore一個JavaScript實用庫,提供了一整套函數(shù)式編程的實用功能,但是沒有擴展任何JavaScript內(nèi)置對象,本文就翻譯了它的源代碼中的注釋,需要的朋友可以參考下
    2015-06-06
  • JavaScript高級程序設(shè)計(第3版)學(xué)習(xí)筆記3 js簡單數(shù)據(jù)類型

    JavaScript高級程序設(shè)計(第3版)學(xué)習(xí)筆記3 js簡單數(shù)據(jù)類型

    數(shù)據(jù)類型是編程語言的磚瓦,是所有你能想象到的復(fù)雜抽象的基礎(chǔ),在現(xiàn)代編程語言中,除了語言本身內(nèi)置的一些簡單數(shù)據(jù)類型外,基本上都提供了用于自定義數(shù)據(jù)類型的語言機制(在C中也可以利用結(jié)構(gòu)體來實現(xiàn)),這些機制在一定程度上也決定了該語言的流行度和生命力
    2012-10-10
  • javascript中常用編程知識

    javascript中常用編程知識

    javascript雖然只是一個腳本語言,但是它完全也是一個編程語言需要我們來學(xué)習(xí)一下,下面是轉(zhuǎn)載的篇關(guān)于javascript中常用的編程知識
    2013-04-04
  • JavaScript中的Math.atan2()方法使用詳解

    JavaScript中的Math.atan2()方法使用詳解

    這篇文章主要介紹了JavaScript中的Math.atan2()方法使用詳解,是JS入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-06-06
  • JavaScript展開操作符(Spread operator)詳解

    JavaScript展開操作符(Spread operator)詳解

    在本篇文章里小編給大家整理的是關(guān)于JavaScript展開操作符(Spread operator)的詳細(xì)介紹以及用法,需要的讀者們參考下。
    2019-07-07
  • javascript定義變量時有var和沒有var的區(qū)別探討

    javascript定義變量時有var和沒有var的區(qū)別探討

    定義變量時省略var是不安全的,不過是合法的。定義的變量的作用域取決于定義的位置
    2014-07-07
  • JavaScript中用let語句聲明作用域的用法講解

    JavaScript中用let語句聲明作用域的用法講解

    首先要注意let是ES6中的東西,起碼是IE10之前的IE瀏覽器兼容要千萬當(dāng)心!嗯...然后我們來看JavaScript中用let語句聲明作用域的用法講解
    2016-05-05

最新評論