筆者剛入行的時候,作的是Android客戶端開發。雖然從事的時間不長,但稍微瞭解一點基本的概念。後來陰差陽錯從事Web開發,一直到如今,因此如今多多少少對Web領域有一丁點的看法。由於這樣,因此有時候會思考下兩者的共性,想找一下兩者相同的點。最近有兩個問題,一直縈繞着:javascript
React
中有state
,props
的概念。組件component
的顯示,數據的體現 大部分都是由state承載,props傳遞。而android基本都是經過setXX
去控制組件和數據。爲何會有這樣的差別?redux
等狀態管理組件都是 flux
架構的實現,也有不少開發者提出FluxAndroid
的概念,但google官方並不認可flux的架構。這是爲何?咱們常常看到這樣的寫法,首先在xml
文件中定義咱們的佈局文件,指定id
等屬性。html
<TextView android:text="@string/hello_world"
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
複製代碼
同時,在Activity
中經過findViewById
去獲取控件的引用,而後進行一系列操做,好比setText
等vue
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = (TextView) findViewById(R.id.textview);
TextView textView = new TextView(this);
textView.setText("Hey, one more TextView");
}
複製代碼
除此以外,咱們還常常看見這樣的寫法,好比:java
setVisibility(View.VISIBLE);
複製代碼
imageview.setBackgroundColor(Color.rgb(213, 0, 0));
複製代碼
你有沒有發現,這些寫法有一個共性,就是都是經過setXXX
去設定值。也就是說,咱們開發者在操做的時候,有這樣的一個模式:react
setXXX
去設定該值後來我發現,這樣的模式在JQuery中也是相似的。jquery
先看下這段代碼。android
<!DOCTYPE html>
<html lang="en">
<head>
<title>learn jQuery</title>
</head>
<body>
<h1>例子1</h1>
<p>若是你點我,我就會消失。</p>
<p>繼續點我!</p>
<p>接着點我!</p>
<script src="jquery-3.3.1.js"></script>
<script type="text/javascript">
//例子1
$(document).ready(function () {
console.log("document is ready");
$("p").click(function () {
$(this).hide();
});
});
</script>
</body>
</html>
複製代碼
首先,咱們先寫了四行HTML
代碼。 而後,經過JQuery
去操做,注意咱們的操做方式。git
咱們經過$("p")
去獲取document
對象中的<p></p>
元素,這是否是很像剛剛在上一節提到的findViewById
,有木有?github
獲取到元素後,經過$(this).hide()
對該元素進行操做。這像不像textView.setText("Hey, one more TextView");
數據庫
若是以爲這段代碼不直觀,來看這個。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Evan JQery</title>
<script src="jquery-3.3.1.js"></script>
<script>
$(document).ready(function(){
$("#btn1").click(function(){
$("#test1").text("Hello world!");
});
$("#btn2").click(function(){
$("#test2").html("<b>Hello world!</b>");
});
$("#btn3").click(function(){
$("#test3").val("Dolly Duck");
});
});
</script>
</head>
<body>
<p id="test1">這是段落。</p>
<p id="test2">這是另外一個段落。</p>
<p>Input field: <input type="text" id="test3" value="Mickey Mouse"></p>
<button id="btn1">設置文本</button>
<button id="btn2">設置 HTML</button>
<button id="btn3">設置值</button>
</body>
</html>
複製代碼
同時,你能夠再本地打開上面的代碼,在瀏覽器中預覽,而後打開開發者模式,在控制檯中輸入,
$("#test3").val("Dolly Ducrrrrk");
複製代碼
你會發現網頁內容也隨之發生了改變。
維基百科這樣說:
Imperative programming is a programming paradigm that uses statements that change a program’s state.
簡單理解,命令式編程,就是命令「機器」如何去作事情(how),這樣無論你想要的是什麼(what),它都會按照你的命令實現。
上述了兩小節都是命令式編程。
提到命令式編程,不得不說下聲明式編程。
聲明式編程,就是告訴「機器」你想要的是什麼(what),讓機器想出如何去作(how)。
打個比方:
Declarative Programming is like asking your friend to draw a landscape. You don’t care how they draw it, that’s up to them. Imperative Programming is like your friend listening to Bob Ross tell them how to paint a landscape. While good ole Bob Ross isn’t exactly commanding, he is giving them step by step directions to get the desired result.
聲明式就像你告訴你朋友畫一幅畫,你不用去管他怎麼畫的細節
命令式就像按照你的命令,你朋友一步步把畫畫出來
若是你以爲有點分不清楚兩者區別,彆着急,先看下下面的案例。
(完成源碼將放在文末可下載)
'use strict';
const e = React.createElement;
class LikeButton extends React.Component {
//https://www.cnblogs.com/johnzhu/p/9016277.html
constructor(props) {
super(props);
this.state = { liked: false };
}
render() {
if (this.state.liked) {
return 'You liked this.';
}
return e(
'button',
{ onClick: () => this.setState({ liked: true }) },
'Like'
);
}
}
const domContainer = document.querySelector('#like_button_container');
ReactDOM.render(e(LikeButton), domContainer);
複製代碼
React
是聲明式的,以上就是體現聲明式很好的例子。
在咱們的render
方法中,渲染一個按鈕,按鈕名字爲「Like」。
按鈕的狀態(也就是文字內容)受state
控制,初始化的state
爲一個JavaScript對象。
this.state = { liked: false };
複製代碼
點擊按鈕以後,觸發事件,改變state
{ onClick: () => this.setState({ liked: true }) }
複製代碼
好,state
在點擊先後發生改變,按鈕的文字是由state
控制。 換句話說,咱們並無直接操做DOM
去改變按鈕的文字內容,只是經過改變state
的狀態。 而state
不一樣的值描述了按鈕在不一樣狀況下應該如何表現不一樣的內容。
The differences here may be subtle. The React example never actually touches an element. it simply declares an element should be rendered given our current state. It does not actually manipulate the DOM itself.
和命令式的區別有點模糊。React
沒有直接操做元素,它只是聲明瞭元素如何在給定的狀態下渲染出特定的結果。
因此,React
的思想和JQuery
有很大不一樣。
When writing React, it’s often good not to think of how you want to accomplish a result, but instead what the component should look like in it’s new state.
使用React
的時候,最好不一樣去想着如何實現某個結果,而是組件在新的狀態下應該有什麼樣的表現。
歇一口氣 ^ __ ^ 歇一口氣
看了React
的寫法,知道它是聲明式,那咱們來看看Vue
是如何體現響應式的。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>VueTest -- evan</title>
</head>
<body>
<div id="app">
<h2>{{product}} are in stock</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
const app = new Vue({
el: '#app', /*element的縮寫*/
data: {
product: 'Boots'
}
})
</script>
</body>
</html>
複製代碼
咱們在模板中指定
<h2>{{product}} are in stock</h2>
複製代碼
而後再Vue
實例中只要product
有值,立馬就渲染出來。
爲了更好的演示,請你打開上述代碼,在瀏覽器中預覽,而後打開控制檯。輸入
app.product = 'you input here'
複製代碼
你就會發現屏幕上的網頁渲染立馬發生了改變。
這就是響應式。
Vue 最獨特的特性之一,是其非侵入性的響應式系統。數據模型僅僅是普通的 JavaScript 對象。而當你修改它們時,視圖會進行更新。
來咱們簡單解釋下 Vue 響應式系統的底層細節。
第一,還記得咱們經過下面的代碼,把一個普通的 JavaScript 對象傳入 Vue 實例做爲 data 選項。
const app = new Vue({
el: '#app', /*element的縮寫*/
data: {
product: 'Boots'
}
})
複製代碼
Vue 將遍歷此對象全部的屬性。
第二,Vue使用 Object.defineProperty
把這些屬性所有轉爲 getter/setter。
第三,每一個Vue Component的render
函數,都都對應一個 watcher 實例。
第四,當 Vue Component render
函數被執行的時候, data 上會被 觸碰(touch)
, 即被讀, getter 方法會被調用, 此時 Vue 會去記錄此 Vue component 所依賴的全部 data。(這一過程被稱爲依賴收集)。
第五,data 被改動時(主要是用戶操做), 即被寫, setter
方法會被調用, 此時 Vue 會去通知全部依賴於此 data 的組件去調用他們的 render 函數進行更新。
還記當時風靡一時的RxJava
, RxAndroid
嘛?現在又有了RxKotlin
,RxDart
。(提醒和我同樣,作過Android開發的同窗們,哈哈~) 他們都是ReactiveX家族的一員。
React
中有state
,props
的概念。組件component
的顯示,數據的體現 大部分都是由state承載,props傳遞。而android基本都是經過setXX
去控制組件和數據。爲何會有這樣的差別?
我的愚見,Android客戶端和Web開發中,有這麼幾點不一樣:
Android的界面UI是有XML
標籤訂義,和DOM
有些不一樣。
瀏覽器刷新的時候,整個DOM
結構都會更新,而Android沒有刷新整個頁面的概念,在Android中,你是經過measure
(測量)、layout
(定位)、draw
(繪製)去顯示一個View
。
不一樣於React中的Component
,Android中的View
,好比ImageView
、TextView
自己內置了不少方法來控制自身屬性,好比setBackground
、setText
。
(歡迎大佬斧正、補充)
redux
等狀態管理組件都是flux
架構的實現,也有不少開發者提出FluxAndroid
的概念,但google官方並不認可flux的架構。這是爲何?
先簡單說明下,Android的架構。
Android架構合集 這篇文章中列舉了不少Android架構,包括官方google的,同時也有Flux
架構模式。
不少開發者受Flux的啓發,寫了適用Android的Flux架構模式。 好比下面幾篇文章。
AndroidFlux ——當ANDROID遇到了FLUX,架構ANDROID應用的新方式。 Flux Architecture on Android
Flux Android Architecture Components using Kotlin
這個問題我尚未很好的答案。我本身以Flux的架構模式去作過了Android的實踐,因爲Android Activity等自身的組件,使得用Flux架構反而比較繁瑣,有點過分設計的味道。但究竟爲什麼Google官方不推薦,歡迎你們補充~
難道這就是Vue這個響應式框架近幾年愈來愈流行的緣由?
放出彩蛋,就是svelte
![在這裏插入圖片描述](img-blog.csdnimg.cn/20190730220… =300x300)
哦對了,文中全部的源碼在這裏哈 點我下載