Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@
* [realtime todo](./sailsjs/3_realtime_todo.md)
- Week4
* [上課用練習](./react/week4_class_example.md)
* [Virtual Dom](./react/virtual_dom.md)
- Week5
* [上課用練習](./react/week5_class_example.md)
- Week6
* [style](./reactnative/style.md)
* [SASS](./SASS/sass.md)
- Week5
* [Redux](./redux/redux.md)
Expand All @@ -51,3 +56,4 @@
* [browserHistory&hashHistory](./browserhistory_hashhistory/ebrowserhistory_hashhistory.md)
- Week6
* [基本元件](./reactnative/basic_bomponents.md)
>>>>>>> upstream/master
36 changes: 36 additions & 0 deletions react/virtual_dom.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#Virtual DOM

##為何要使用Virtual Dom?

DOM 操作的效能成本非常的高,React 為了解決開發者在手動操作 DOM 時可能造成的效能低落或失誤,建立了一套虛擬 DOM( Virtual DOM,以下簡稱 VDOM)的機制,程式記憶體中將有一份對應真正 DOM 的 VDOM 物件,以代管 UI 儲存的資料與邏輯。當一個 UI 因為資料改變而需要進行畫面變動的時候,React 會根據新的 UI 狀態重繪一份新的 VDOM Tree,並且與變動前的舊 VDOM Tree 以高效率的 Diff 演算法進行比對,然後其中的差異才會真正的由 React 自動幫你更新到實際的 DOM 上,反應出畫面的變更。

透過 VDOM 的機制,開發者將不必煩惱如何操作 DOM,而可以專心於撰寫 UI 的定義與互動邏輯。並且由於 React 能夠自動去最佳化的處理 DOM 操作,前端 UI 程式將可以有效的降低操作成本而達到優秀的效能。


###從 Virtual DOM 生成DOM 帶來了一些好處

* 標籤之間的空格從一開始就被排除,不會帶來意外的空白元素的字符串被自動轉義,不會那麼容易導致代碼注入

* JSON 的Tree 很容易組合,組件化很自然就實現出來了
同時,JavaScript 可以在 Node.js 和瀏覽器同時運行,能夠共享代碼同時得益於 DOM 會自動完成Diff 和 Patch,DOM 樹就能夠自動隨著數據改變進行更新,更新 DOM 。就像是 MVC 描述的那樣,Model 被更新,View 就跟著更新,就這麼簡單


###Virtual DOM

* 是一份純資料的 Tree 物件,對應到實際的 DOM

* 是自定義 Component 提供了中介的虛擬層,讓開發者能描述 UI 樣貌與邏輯

我們透過定義 Component 來表達「UI 什麼情況該如何呈現」。而「要用什麼手段來達到這個畫面改變(如何操作 DOM)」 ,React 則會自動幫你做,而且絕大多數情況下都比你自己來要做的更好

###Single Source of Truth

* UI 要長得如何,應當是取決於當時的 Model 資料以及 UI 狀態而決定

* 把畫面全部洗掉重新再畫,顯示結果通常一定是正確的

* 每次都重繪全部的實體 DOM 顯然是不可行,但是重繪 VDOM 則相對高效許多


當畫面需要改變時,根據最新的 UI 狀態重繪出新的 VDOM Tree並與改變前的舊 VDOM Tree 進行全面式的比較與計算,其中新舊差異的地方,才真的會在實際的 DOM 上發生操作改變

4 changes: 4 additions & 0 deletions react/week5_class_example-copy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# 上課用練習
請各位先將以下兩個專案 __fork 到自己的 github__,然後 `git clone` 並都 `npm install`
* [React Router Practice](https://github.com/tz5514/hellojs-react-router-practice)
* [Redux Practice](https://github.com/tz5514/hellojs-redux-practice)
Binary file added reactnative/pic.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
299 changes: 299 additions & 0 deletions reactnative/style.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,299 @@
I##StyleSheet.create

駝峰式的 CSS 屬性名稱

```
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
});

```
類似CSS的樣式程式碼撰寫方式

##使用樣式

* 單樣式使用方式

`<View style={styles.container} />`

* 使用多個樣式

`<View style={[styles.container, style.style2]} />`

與 Object.assign 相同,若有衝突,右邊優先

* 以條件選擇樣式

`<View style={[styles.base,this.state.active && styles.active]} />`

預設執行前項`styles.base`樣式,當後面`this.state.active`狀態改變為true或成立時執行後項`styles.active`的樣式


##樣式變換

目標:按按鈕變換按鈕顏色

* 建立樣式

* 先在下方const styles內新增樣式blue和green,如下

```
const styles = StyleSheet.create({
blue:{
backgroundColor: 'blue'
},
green:{
backgroundColor: 'green'
}
});
```

* 建立按鈕

* 事件需匯入TouchableOpacity來產生按鈕,如下

```
import {
TouchableOpacity
} from 'react-native';
```

* 按鈕功能判斷

* 點擊改變true或false來判斷是否點擊來做顏色的變換
在constructor(props)中設定active初值,如下

```
constructor(props) {
super(props)
this.state = {
active: false,
}
}
```

* 設定onPress功能的狀態變化

```
onPress = () => {
this.setState({active: !this.state.active});
}
```

* 在render中顯示button的按鈕

```
<TouchableOpacity onPress={this.onPress}>
<Text>
button
</Text>
</TouchableOpacity>
```

* 在onPress={this.onPress}加入樣式的變化判斷

```
style={[styles.blue, this.state.active && styles.green]}
```

程式碼整段會變成如下

```
<TouchableOpacity onPress={this.onPress} style={[styles.blue, this.state.active && styles.green]}>
<Text>
button
</Text>
</TouchableOpacity>
```

說明```style={[styles.blue, this.state.active && styles.green]}```

1. 畫面預設會先執行styles.blue

2. 按下按鈕後this.state.active成立變成true就會執行styles.green

3. 再按一下this.state.active變成false就會回到預設styles.blue

所有程式碼

要複製直接套用記得把裡面有`app2`的改成你的檔名

```
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
TouchableOpacity
} from 'react-native';

class app2 extends Component {
constructor(props) {
super(props)
this.state = {
active: false,
}
}
onPress = () => {
this.setState({active: !this.state.active});
}

render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={this.onPress} style={[styles.blue, this.state.active && styles.green]}>
<Text>
button
</Text>
</TouchableOpacity>
<Text style={styles.instructions}>
style 樣式練習{'\n'}
按按鈕變換按鈕顏色
</Text>
</View>
);
}
}

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
blue:{
backgroundColor: 'blue'
},
green:{
backgroundColor: 'green'
}
});

AppRegistry.registerComponent('app2', () => app2);
```

##使用Flexbox布局

目標:畫面佈局與分割

* 排版方向,預設是 column
flexDirection 方向排版比例

將以下加入到render中
畫面中會變成垂直2:1的顏色條(亮藍色:亮綠色)

```
<View style={styles.container}>
<View style={{
flex: 2,
backgroundColor: 'lightblue'
}}>
<Text>View1</Text>
</View>
<View style={{
flex: 1,
backgroundColor: 'lightgreen'
}} >
<Text>View2</Text>
</View>
</View>
```

###justifyContent & alignItems

* justifyContent

flexDirection方向的子元素排版

能用的值:flex-start, center, flex-end, space-around, space-between


* alignItems

垂直 flexDirection 方向的子元素排版

能用的值:flex-start, center, flex-end, stretch

如果只要設定自己元素的排版用alignSelf

例如:alignSelf:flex-start這是設定靠上對齊畫面中的分割

以下範例圖示

![](pic.png)

以下所有程式碼

```
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';

class app3 extends Component {
render() {
return (
<View style={styles.container}>

<View style={{flex: 1,backgroundColor: 'green'}}>
{/*左邊(由左而右)*/}
<Text>左邊</Text>
</View>
<View style={{flex: 1,backgroundColor: 'gray'}} >
{/*中間這一塊(由左而右)*/}
<View style={{flex: 1,backgroundColor: 'white' }} >
{/*中間裡面包含上面一塊(由上而下)*/}
<Text>中上</Text>
</View>
<View style={{flex: 1,backgroundColor: 'red'}}>
{/*中間裡面包含下面一塊(由上而下)*/}
<Text>中下</Text>
</View>
</View>

<View style={{flex: 1,backgroundColor: 'blue'}} >
{/*右邊(由左而右)*/}
<Text>右邊</Text>
</View>
</View>
);
}
}

const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection:'row', //這裡設定由左而右排,若未設定預設是從上而下
justifyContent: 'center',
alignItems: 'stretch',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});

AppRegistry.registerComponent('app3', () => app3);
```