深入淺出分析vue2和vue3的區(qū)別
前言
vue2和vu3之前的區(qū)別,一直以來(lái)是面試必考題目,如何回答,回答的層次決定了面試者的對(duì)于vue2,3的理解,以及對(duì)于vue3目前穩(wěn)定版本發(fā)展的方向的了解,即考察使用程度,又考察了學(xué)習(xí)能力,可以說(shuō)是回答即可以很簡(jiǎn)單,也可以很不簡(jiǎn)單,這里需要注意的是面試官的面試程度,需要我們層層遞進(jìn),由淺入深來(lái)回答,這樣可以體現(xiàn)出面試者的考慮全面,又能體現(xiàn)知識(shí)廣度。簡(jiǎn)而言之,vue2升級(jí)vue3之后變得更快,更輕,協(xié)作更方便。無(wú)論對(duì)于我們開(kāi)發(fā)者的體驗(yàn)或者用戶使用方面都是升級(jí)優(yōu)化,但是本質(zhì)區(qū)別是什么,下面分為幾個(gè)部分進(jìn)行講解。
vue2 vs vue3
對(duì)比 | vue2 | vue3 |
腳手架 | 命令式 | 可視化創(chuàng)建腳?架 |
組件通信 | 見(jiàn)下文 | 見(jiàn)下文 |
數(shù)據(jù)監(jiān)聽(tīng) | watch,computed | watch,watchEffect,computed |
雙向綁定 | Object.defineProperty | ProxyAPI |
?命周期 | 見(jiàn)下文 | 見(jiàn)下文 |
api | 選項(xiàng)式 | 組合式 |
雙向綁定更新
vue2 的雙向數(shù)據(jù)綁定是利?ES5 的?個(gè) API ,Object.defineProperty()對(duì)數(shù)據(jù)進(jìn)?劫持 結(jié)合 發(fā)布訂閱模式的?式來(lái)實(shí)現(xiàn)的。
vue3 中使?了 ES6 的 ProxyAPI 對(duì)數(shù)據(jù)代理,通過(guò) reactive() 函數(shù)給每?個(gè)對(duì)象都包?層 Proxy,通過(guò) Proxy 監(jiān)聽(tīng)屬性的變化,從? 實(shí)現(xiàn)對(duì)數(shù)據(jù)的監(jiān)控。
這?是相?于vue2版本,使?proxy的優(yōu)勢(shì)如下
1.defineProperty只能監(jiān)聽(tīng)某個(gè)屬性,不能對(duì)全對(duì)象監(jiān)聽(tīng) 可以省去for in、閉包等內(nèi)容來(lái)提升效率(直接綁定整個(gè)對(duì)象即可)
2.可以監(jiān)聽(tīng)數(shù)組,不?再去單獨(dú)的對(duì)數(shù)組做特異性操作,通過(guò)Proxy可以直接攔截所有對(duì)象類型數(shù)據(jù)的操作,完美?持對(duì)數(shù)組的監(jiān)聽(tīng)。
實(shí)例化
Vue2.x中new出的實(shí)例對(duì)象,所有的東西都在這個(gè)vue對(duì)象上,這樣其實(shí)?論你?到還是沒(méi)?到,都會(huì)跑?遍,這樣不僅提?了性能消耗,也?疑增加了?戶加載時(shí)間。
?vue3.0中可以?ES module imports按需引?,如:keep-alive內(nèi)置組件、v-model指令,等等,不僅我們開(kāi)發(fā)起來(lái)更加的便捷,減少 了內(nèi)存消耗,也同時(shí)減少了?戶加載時(shí)間,優(yōu)化?戶體驗(yàn)。
生命周期
引用掘金圖片如下:
獲取props
vue2在script代碼塊可以直接獲取props,vue3通過(guò)setup指令傳遞
vue2:console.log('props',this.xxx) vue3:setup(props,context){ console.log('props',props) }
數(shù)據(jù)和方法的定義
Vue2使?的是選項(xiàng)類型API(Options API),Vue3使?的是合成型API(Composition API)
Vue2:
data() { return {}; }, methods:{ }
Vue3:
數(shù)據(jù)和?法都定義在setup中,并統(tǒng)?進(jìn)?return{}
給父組件傳值emit
vue2:this.$emit() vue3:setup(props,context){context.emit()}
watchEffect
Vue3中除了watch,還引入了副作用監(jiān)聽(tīng)函數(shù)watchEffect,用過(guò)之后我發(fā)現(xiàn)它和React中的useEffect很像,只不過(guò)watchEffect不需要傳入依賴項(xiàng)。
那么什么是watchEffect呢?
watchEffect它會(huì)立即執(zhí)行傳入的一個(gè)函數(shù),同時(shí)響應(yīng)式追蹤其依賴,并在其依賴變更時(shí)重新運(yùn)行該函數(shù)。
computed和watch所依賴的數(shù)據(jù)必須是響應(yīng)式的。Vue3引入了watchEffect,watchEffect 相當(dāng)于將 watch 的依賴源和回調(diào)函數(shù)合并,當(dāng)任何你有用到的響應(yīng)式依賴更新時(shí),該回調(diào)函數(shù)便會(huì)重新執(zhí)行。不同于 watch的是watchEffect的回調(diào)函數(shù)會(huì)被立即執(zhí)行,即({ immediate: true })。
組件通信
注意
props中數(shù)據(jù)流是單項(xiàng)的,即子組件不可改變父組件傳來(lái)的值
在組合式API中,如果想在子組件中用其它變量接收props的值時(shí)需要使用toRef將props中的屬性轉(zhuǎn)為響應(yīng)式。
attrs和listeners
子組件使用$attrs可以獲得父組件除了props傳遞的屬性和特性綁定屬性 (class和 style)之外的所有屬性。
子組件使用$listeners可以獲得父組件(不含.native修飾器的)所有v-on事件監(jiān)聽(tīng)器,在Vue3中已經(jīng)不再使用;但是Vue3中的attrs不僅可以獲得父組件傳來(lái)的屬性也可以獲得父組件v-on事件監(jiān)聽(tīng)器
路由
vue3和vue2路由常用功能只是寫法上有些區(qū)別:
vue3的beforeRouteEnter
作為路由守衛(wèi)的示例是因?yàn)樗?code>setup語(yǔ)法糖中是無(wú)法使用的;大家都知道setup
中組件實(shí)例已經(jīng)創(chuàng)建,是能夠獲取到組件實(shí)例的。而beforeRouteEnter
是再進(jìn)入路由前觸發(fā)的,此時(shí)組件還未創(chuàng)建,所以是無(wú)法用在setup
中的;如果想在setup語(yǔ)法糖中使用則需要再寫一個(gè)script
如下:
<script> export default { beforeRouteEnter(to, from, next) { // 在渲染該組件的對(duì)應(yīng)路由被 confirm 前調(diào)用 next() }, }; </script>
vue3路由寫法:
<script> import { defineComponent } from 'vue' import { useRoute, useRouter } from 'vue-router' export default defineComponent({ beforeRouteEnter (to, from, next) { // 在渲染該組件的對(duì)應(yīng)路由被 confirm 前調(diào)用 next() }, beforeRouteLeave ((to, from, next)=>{//離開(kāi)當(dāng)前的組件,觸發(fā) next() }), beforeRouteLeave((to, from, next)=>{//離開(kāi)當(dāng)前的組件,觸發(fā) next() }), setup() { const router = useRouter() const route = useRoute() const toPage = () => { router.push(xxx) } //獲取params 注意是route route.params //獲取query route.query return { toPage } }, }); </script>
vue2寫法:
<script> export default { beforeRouteEnter (to, from, next) { // 在渲染該組件的對(duì)應(yīng)路由被 confirm 前調(diào)用 next() }, beforeRouteEnter (to, from, next) { // 在渲染該組件的對(duì)應(yīng)路由被 confirm 前調(diào)用 next() }, beforeRouteLeave ((to, from, next)=>{//離開(kāi)當(dāng)前的組件,觸發(fā) next() }), beforeRouteLeave((to, from, next)=>{//離開(kāi)當(dāng)前的組件,觸發(fā) next() }), methods:{ toPage(){ //路由跳轉(zhuǎn) this.$router.push(xxx) } }, created(){ //獲取params this.$route.params //獲取query this.$route.query } } </script>
總結(jié)
vue2和vue3比較還是有很多不一樣的地方,比如setup語(yǔ)法糖的形式最為便捷而且更符合開(kāi)發(fā)者習(xí)慣,未來(lái)vue3將會(huì)大面積使用這種規(guī)則,這樣更加符合開(kāi)發(fā)習(xí)慣和降低后續(xù)維護(hù)的成本,還有目前Vue3已經(jīng)成為了Vue的默認(rèn)版本,后續(xù)維護(hù)應(yīng)該也會(huì)以Vue3為主。希望各位同學(xué)趕緊學(xué)起來(lái)吧~
相關(guān)文章
詳解在Vue中如何使用axios跨域訪問(wèn)數(shù)據(jù)
本篇文章主要介紹了在Vue中如何使用axios跨域訪問(wèn)數(shù)據(jù),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-07-07詳解vue computed的緩存實(shí)現(xiàn)原理
這篇文章主要介紹了vue computed的緩存實(shí)現(xiàn)原理,幫助大家更好的理解和學(xué)習(xí)使用vue,感興趣的朋友可以了解下2021-04-04vue.js組件vue-waterfall-easy實(shí)現(xiàn)瀑布流效果
這篇文章主要為大家詳細(xì)介紹了vue.js實(shí)現(xiàn)瀑布流之vue-waterfall-easy的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08詳解Vue-cli3 項(xiàng)目在安卓低版本系統(tǒng)和IE上白屏問(wèn)題解決
這篇文章主要介紹了Vue-cli3 項(xiàng)目在安卓低版本系統(tǒng)和 IE 上白屏問(wèn)題解決,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-04-04Vue動(dòng)畫之第三方類庫(kù)實(shí)現(xiàn)動(dòng)畫方式
這篇文章主要介紹了Vue動(dòng)畫之第三方類庫(kù)實(shí)現(xiàn)動(dòng)畫方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04十個(gè)有用的自定義Vue鉤子函數(shù)總結(jié)
這篇文章主要為大家介紹了十個(gè)Vue.js中有用的自定義鉤子,讓我們的代碼更加好看。文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-04-04Vue.js遞歸組件實(shí)現(xiàn)組織架構(gòu)樹(shù)和選人功能
這篇文章主要介紹了Vue.js遞歸組件實(shí)現(xiàn)組織架構(gòu)樹(shù)和選人功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07