對于Vue 和 React框架想必大家都不陌生 ,這兩個都是目前非常有名的前端框架。但是對于它們二者之間的區別,很多人還不是太了解,今天將為大家詳細介紹這兩者之間的區別,希望可以幫助大家更好地理解它們兩者之間的差異。
【推薦課程:React教程、Vue.js教程】
1. 目標
構建一個標準的待辦事項應用程序,用來允許用戶添加和刪除列表中的項目。這兩個應用程序都使用默認的 CLI(command-line interface,命令行界面) 構建,React 使用 create-react-app,Vue 使用 vue-cli
兩個應用程序的外觀如下:
兩個應用程序的 CSS 代碼幾乎一樣,但這些代碼的位置存在差異,如下圖所示:
從圖中可以看出它們的結構幾乎完全相同。唯一的區別在于 React App 擁有三個 CSS 文件,而 Vue App 中沒有 CSS 文件。這是因為
React的 create-react-app 組件需要一個附帶文件來保存其樣式,而 Vue CLI 采用全包方法,其樣式在實際組件文件中聲明。
兩種不同的策略得到的結果是一樣的,相信開發者很快能夠掌握這兩種不同的策略。開發者可以根據自己的偏好做出選擇,你會聽到開發
社區關于如何構建 CSS 的大量討論。以上,我們遵循兩個 CLI 列出了代碼結構。
在我們進一步討論之前,先快速看一下典型的 Vue 和 React 組件的外觀:
現在開始,讓我們深入探究其中的細節!
2. 如何修改數據
修改數據就是把已經存儲好的數據進行更改。在這一點上,React 和 Vue 的處理方式有所區別。Vue 本質上會創建一個數據對象,其中的數據可以自由更改;React 則創建一個狀態對象,更改數據需要一些額外的操作。React 之所以需要額外的操作有著自己的理由,稍后我會深入介紹。在此之前,我們先看看 Vue 中的數據對象和 React 中的狀態對象:
Vue 數據對象
React 狀態對象
從圖中可以看出,我們傳入了相同的數據,但它們的標記方法不同。因此,將初始數據傳遞到組件的方式非常相似。但正如我們提到的那樣,在兩個框架中更改數據的方式有所不同。
例:我們要修改一個名為 name: ‘Sunil’ 的數據元素
在 Vue 中,我們通過調用 this.name 來引用它。我們也可以通過調用 this.name ='John' 來更新它。這樣一來,名字就被成功改為了 “Jhon”。
在 React 中,我們通過調用 this.state.name 來引用同一段數據。現在關鍵的區別在于,我們不能簡單地寫成 this.state.name='John',因為 React 有限制機制,它會阻止這種簡單的修改方式。在 React 中,我們需要這樣寫:this.setState({name:'John'})。
雖然與 Vue 中實現的結果一樣,但是 React 的操作更為繁瑣。原因在于Vue 在每次更新數據時默認組合了自己的 setState 版本。而React 需要 setState,然后再更新其內部數據。
現在我們知道如何更改數據了,接下來看看如何在待辦應用程序中添加新的事項。
3. 添加新的待辦事項
React 的實現方法
createNewToDoItem = () => { this.setState( ({ list, todo }) => ({ list: [ ...list, { todo } ], todo: '' }) ); };
在 React 中,我們的輸入字段有一個名為 value 的屬性。這個 value 通過使用幾個函數自動更新,這些函數綁定在一起以創建雙向綁定。我們通過在輸入字段上附加一個 onChange 事件監聽器來創建這種形式的雙向綁定。如下所示:
<input type="text" value={this.state.todo} onChange={this.handleInput}/>
只要輸入字段的值發生更改,handleInput 函數就會運行。它通過將狀態對象設置為輸入字段中的任何內容來更新狀態對象內的 todo。handleInput 函數如下:
handleInput = e => { this.setState({ todo: e.target.value }); };
現在,只要用戶按下頁面上的 + 按鈕添加新項目,createNewToDoItem 函數就會運行 this.setState 并向其傳遞一個函數。該函數有兩個參數,第一個是來自狀態對象的整個列表數組,第二個是由 handleInput 函數更新的todo。然后該函數返回一個新對象,該對象包含之前的整個列表,并在其末尾添加todo。整個列表是通過使用擴展運算符添加的。
最后,我們將 todo 設置為空字符串,它會自動更新輸入字段中的 value。
Vue 的實現方法
createNewToDoItem() { this.list.push( { 'todo': this.todo } ); this.todo = ''; }
在 Vue 中,我們的輸入字段中有一個名為 v-model 的句柄。這實現了**雙向綁定。輸入字段代碼如下:
<input type="text" v-model="todo"/>
V-Model 將輸入字段的內容綁定到名為 toDoItem 的數據對象的鍵(key)上。當頁面加載時,我們將 toDoItem 設置為空字符串,比如:todo:' '。如果已經存在數據,例如 todo:'添加文本處',輸入字段將加載添加文本處的輸入內容。無論如何,將其作為空字符串,我們在輸入字段中鍵入的任何文本都會綁定到 todo。這實際上是雙向綁定(輸入字段可以更新數據對象,數據對象可以更新輸入字段)。
因此,回顧前面的 createNewToDoItem() 代碼塊,我們將 todo 的內容存放到列表數組中 ,然后將 todo 改為空字符串。
4. 刪除待辦事項
React 的實現方法
deleteItem = indexToDelete => { this.setState(({ list }) => ({ list: list.filter((toDo, index) => index !== indexToDelete) })); };
盡管 deleteItem 函數位于 ToDo.js 文件中,但是從 ToDoItem.js 文件中引用它也很容易,將 deleteItem() 函數作為 上的 prop 傳遞:
<ToDoItem deleteItem={this.deleteItem.bind(this, key)}/>
這會將該函數傳遞給子組件,使其可以訪問。我們綁定了 this 并傳遞 key 參數,當用戶點擊刪除項時,函數通過 key 區分用戶點擊的是哪一條 ToDoItem 。然后,在ToDoItem 組件內部,我們執行以下操作:
<div className=”ToDoItem-Delete” onClick={this.props.deleteItem}>-</div>
想要引用位于父組件內部的函數,只需引用 this.props.deleteItem 即可。
Vue 的實現方法
onDeleteItem(todo){ this.list = this.list.filter(item => item !== todo); }
Vue 的實現方法稍有不同,我們需要做到以下三點:
Step 1:首先,在元素上調用函數:
<div class=”ToDoItem-Delete” @click=”deleteItem(todo)”>-</div>
Step 2:然后我們必須創建一個 emit 函數,將其作為子組件的內部方法(在本例中為ToDoItem.vue),如下所示:
deleteItem(todo) { this.$emit('delete', todo) }
Step 3:之后,你會發現,當我們添加 ToDo.vue的 ToDoItem.vue 時,實際上引用了一個函數:
<ToDoItem v-for="todo in list" :todo="todo" @delete="onDeleteItem" // <-- this :) :key="todo.id" />
這就是所謂的自定義事件監聽器。它會監聽任何使用 'delete' 字符串的觸發事件。一旦監聽到事件,它會觸發一個名為 onDeleteItem 的函數。此函數位于 ToDo.vue 內部,而不是 ToDoItem.vue。如前所述,該函數只是過濾數據對象內的 todo 數組 ,以刪除被點擊的待辦事項。
在 Vue 示例中還需要注意的是,我們可以在 @click 偵聽器中編寫 $emit 部分,這樣更加簡單,如下所示:
<div class=”ToDoItem-Delete” @click=”$emit(‘delete’, todo)”>-</div>
如果你喜歡,這樣做可以把 3 步減少到 2 步。
React 中的子組件可以通過 this.props 訪問父函數,而在 Vue 中,你需要從子組件中發出事件,父組件來收集事件。
5. 如何傳遞事件監聽器
React 的實現方法
事件監聽器處理簡單事件(比如點擊)非常直接。我們為待辦事項創建了點擊事件,用于創建新的待辦事項,代碼如下:
<div className=”ToDo-Add” onClick={this.createNewToDoItem}>+</div>
非常簡單,就像使用 vanilla JS 處理內聯 onClick 一樣。正如前文所述,只要按下回車按鈕,設置事件監聽器就需要花費更長的時間。這需要輸入標簽處理 onKeyPress 事件,代碼如下:
<input type=”text” onKeyPress={this.handleKeyPress}/>
該函數只要識別到'enter'鍵被按下,它就會觸發 **createNewToDoItem** 函數,代碼如下所示:
handleKeyPress = (e) => { if (e.key === ‘Enter’) { this.createNewToDoItem(); } };
Vue 的實現方法
Vue 的事件監聽器更加直接。我們只需要使用一個簡單的 @ 符號,就可以構建出我們想要的事件監聽器。例如,想要添加 click 事件監聽器,代碼:
<div class=”ToDo-Add” @click=”createNewToDoItem()”>+</div>
注意:@click 實際上是 v-on:click 的簡寫。Vue 事件監聽器很強大,你可以為其選擇屬性,例如 .once 可以防止事件監聽器被多次觸發。此外,它還包含很多快捷方式。按下回車按鈕時,React 就需要花費更長的時間來創建事件監聽器,從而創建新的 ToDo 項目。在 Vue,代碼如下:
<input type=”text” v-on:keyup.enter=”createNewToDoItem”/>
6. 如何將數據傳遞給子組件
React 的實現方法
在 React 中,我們將 props 傳遞到子組件的創建處。比如:
<ToDoItem key={key} item={todo} />
此處我們向 ToDoItem 組件傳遞了兩個 prop。之后,我們可以在子組件中通過 this.props 引用它們
因此,想要訪問 item.todo prop,我們只需調用this.props.item 。
Vue 的實現方法
在 Vue 中,我們將 props 傳遞到子組件創建處的方式如下:
<ToDoItem v-for="todo in list" :todo="todo" :key="todo.id" @delete="onDeleteItem" />
我們將它們傳遞給子組件中的 props 數組,如:props:['id','todo']。然后可以在子組件中通過名字引用它們。
7. 如何將數據發送回父組件
React 的實現方法
我們首先將函數傳遞給子組件,方法是在我們調用子組件時將其引用為 prop。
然后我們通過引用 this.props.whateverTheFunctionIsCalled,為子組件添加調用函數,例如 onClick。然后,這將觸發父組件中的函
數。刪除待辦事項一節中詳細介紹了整個過程。
Vue 的實現方法
在子組件中我們只需編寫一個函數,將一個值發送回父函數。在父組件中編寫一個函數來監聽子組件何時發出該值的事件,監聽到事件之后觸發函數調用。同樣,刪除待辦事項一節中詳細介紹了整個過程。
8. 總結
通過介紹了如何添加、刪除和更改數據,以 prop 形式從父組件到子組件傳遞數據,以及通過事件監聽器的形式將數據從子組件發送到父組件等方法來理解React 和 Vue 之間的差異,希望通過本文的內容有助于大家理解這兩個框架
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com