最開的網頁只有文字,也就html部分,隨着互聯網發展,網頁內容的豐富多彩,網頁不僅僅限於瀏覽,而是需要互動。爲解決這個問題,先後出現了js和css。
解決這個問題的思路,各有利弊:
1.優點
css很靈活,程序員可以有能力隨心所欲的控制網頁。
JS很強大,可以隨心所欲的控制用戶的行爲。
分工明確,更容易專業化,符合社會趨勢,越來越精細化。
2.缺點
分工必然會涉及到協作,協作必然會存在這樣的問題:怎麼讓溝通和切換工作場景狀態保持一致。
舉個現實的例子,你把一個前端項目分給三個人做,一個人切圖,一個人數據交互,一個寫後臺。那麼如果切圖的人改網頁上的東西,一定會影響另外兩個人,怎麼保證三個人修改頁面狀態一致,這就是個問題。
根本性的解決方案
web components
解決問題的思路:
讓網頁由一個個積木組成,每一個積木通過良好的定義規定好接口和規範,以及統一的實現。這個本質上和我們用同一個型號的磚頭可以蓋出不同的房子沒什麼兩樣。
目前問題:
兼容性不好、思路不成熟、不好用
普遍的解決方案
1.mvc方案
MVC很簡單,還是拿剛纔的三個人工作舉例:
現在寫數據交互的人說了,切圖的你啥也不用想,你就按照我們商定的標準切圖,別瞎搞。後臺你也是,我想要啥數據你就給我啥格式,別自己瞎搞,我統一去合併文件。
這就是MVC思想,純切圖的就是view,寫後臺搞數據的就是model,寫數據交互讓前後臺對應起來的就是c。
MVC的初衷是好的,
MVC要實現的目標是將軟件用戶界面和業務邏輯分離以使代碼可擴展性、可複用性、可維護性、靈活性加強。
結果有兩個問題:
1.很多程序員將MVC當成了三層架構在用,寫出來的東西既不是三成架構也不是MVC,倒是像一個什麼都不是的四不像。三層架構的核心思想是面向接口編程和各層之間的解耦和可替換性,MVC並不具備這樣的思想和能力,很多人誤解了它。
2.即使不誤解,這樣做也有問題從我們的例子可以看出來,C端業務過重,一來造成混亂,二來對C端業務能力要求也高。Controller會越來越難維護
3.手動管理各個過程很費勁。
舉個例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
window.onload = function(){
var oUl = document.getElementById('ul1');
var aPrev = document.querySelectorAll('.prev');
var aNext = document.querySelectorAll('.next');
for(var i=0;i<aPrev.length;i++){
aPrev[i].onclick = function(){
var oParent = this.parentNode;
var oPrev = oParent.previousElementSibling || oParent.previousSibling;
if(oParent == oUl.children[0]){
alert('到頭了!');
return;
}
oUl.insertBefore(oParent,oPrev);
}
}
for(var i=0;i<aNext.length;i++){
aNext[i].onclick = function(){
var oParent = this.parentNode;
var oNext = oParent.nextElementSibling || oParent.nextSibling;
var oNext2 = oNext.nextElementSibling || oNext.nextSibling;
if(oParent == oUl.children[oUl.children.length-1]){
alert('到底了!');
return;
}
oUl.insertBefore(oParent,oNext2);
}
}
};
</script>
</head>
<body>
<ul id="ul1">
<li>
<span>1、111111111</span>
<a href="javascript:;" class='prev'>上移</a>
<a href="javascript:;" class='next'>下移</a>
</li>
<li>
<span>2、222222222</span>
<a href="javascript:;" class='prev'>上移</a>
<a href="javascript:;" class='next'>下移</a>
</li>
<li>
<span>3、3333333333</span>
<a href="javascript:;" class='prev'>上移</a>
<a href="javascript:;" class='next'>下移</a>
</li>
<li>
<span>4、4444444444</span>
<a href="javascript:;" class='prev'>上移</a>
<a href="javascript:;" class='next'>下移</a>
</li>
<li>
<span>5、5555555555</span>
<a href="javascript:;" class='prev'>上移</a>
<a href="javascript:;" class='next'>下移</a>
</li>
</ul>
</body>
</html>
效果:
即使用MVC的方式,也會涉及到大量的過程管理,DOM操作,比如用控制器控制上下移動,既要考慮元素位置,也要考慮點擊按鈕的行爲。整個過程繁瑣、複雜。
2.react方式
那我們換一個思路,有沒有可能我只考慮數據的變化,DOM的操作不考慮。比如:
我現在根本就不去想插到誰後面的後面的前面,我只考慮一件事,我把四條數據看做一個數組中的數據,上下移動我玩的就是數組,數組對了,那麼位置不就正確了嗎?這就是react的方式。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
window.onload = function(){
var aEles = document.getElementsByTagName('li');
var oUl = document.getElementById('ul1');
arrAEles = [...aEles];
var aPrev = document.getElementsByClassName('prev');
for(let i = 0;i<aPrev.length;i++){
//上移
//[1,2,3,4] =>[2,]
aPrev[i].onclick = function(){
if(i ==0){
alert('到頂了');
return;
}
//這裏我只是說明,我們可以只考慮數據順序
[arrAEles[i],arrAEles[i-1]] = [arrAEles[i-1],arrAEles[i]];
SortEles(arrAEles);
};
}
var aNext = document.getElementsByClassName('prev');
//我們根本不用管DOM 怎麼操作的
function SortEles(arrAEles){
oUl.innerHTML = '';
for(var i = 0;i<arrAEles.length;i++){
oUl.appendChild(arrAEles[i]);
}
}
};
</script>
</head>
<body>
<ul id="ul1">
<li>
<span>1、111111111</span>
<a href="javascript:;" class='prev'>上移</a>
<a href="javascript:;" class='next'>下移</a>
</li>
<li>
<span>2、222222222</span>
<a href="javascript:;" class='prev'>上移</a>
<a href="javascript:;" class='next'>下移</a>
</li>
<li>
<span>3、3333333333</span>
<a href="javascript:;" class='prev'>上移</a>
<a href="javascript:;" class='next'>下移</a>
</li>
<li>
<span>4、4444444444</span>
<a href="javascript:;" class='prev'>上移</a>
<a href="javascript:;" class='next'>下移</a>
</li>
<li>
<span>5、5555555555</span>
<a href="javascript:;" class='prev'>上移</a>
<a href="javascript:;" class='next'>下移</a>
</li>
</ul>
</body>
</html>
這裏我們只是實現了一個思路,並沒有具體去實現,但是大家已經能感受到不操作DOM的好處。
一句話:數據對了,什麼都對了。所謂的react狀態管理,其實就是數據管理。
結語:
- 首先我們說了HTML、css、JS分離造成問題,促使了React的出現;
- 然後我們瞭解了根本解決方案(web components )需要面對的問題;
- 接着我們講了普遍解決方案,mvc的方式;
- 最後我們說了爲什麼最終大家走到了react方式這一步。
下一篇文章我們聊聊React是什麼,以及React組件化的實現。