Vue2和Vue3的區(qū)別

vue2 vs vue3

對比 vue2 vue3
腳手架 命令式 可視化創(chuàng)建腳?架
組件通信 見下文 見下文
數(shù)據(jù)監(jiān)聽 watch,computed watch,watchEffect,computed
雙向綁定 Object.defineProperty ProxyAPI
?命周期 見下文 見下文
api 選項式 組合式

雙向綁定更新

vue2 的雙向數(shù)據(jù)綁定是利?ES5 的?個 API ,Object.defineProperty()對數(shù)據(jù)進?劫持 結(jié)合 發(fā)布訂閱模式的?式來實現(xiàn)的。

vue3 中使?了 ES6 的 ProxyAPI 對數(shù)據(jù)代理,通過 reactive() 函數(shù)給每?個對象都包?層 Proxy,通過 Proxy 監(jiān)聽屬性的變化,從? 實現(xiàn)對數(shù)據(jù)的監(jiān)控。

這?是相?于vue2版本,使?proxy的優(yōu)勢如下

1.defineProperty只能監(jiān)聽某個屬性,不能對全對象監(jiān)聽 可以省去for in、閉包等內(nèi)容來提升效率(直接綁定整個對象即可)

2.可以監(jiān)聽數(shù)組,不?再去單獨的對數(shù)組做特異性操作,通過Proxy可以直接攔截所有對象類型數(shù)據(jù)的操作,完美?持對數(shù)組的監(jiān)聽。

實例化

Vue2.x中new出的實例對象,所有的東西都在這個vue對象上,這樣其實?論你?到還是沒?到,都會跑?遍,這樣不僅提?了性能消耗,也?疑增加了?戶加載時間。

?vue3.0中可以?ES module imports按需引?,如:keep-alive內(nèi)置組件、v-model指令,等等,不僅我們開發(fā)起來更加的便捷,減少 了內(nèi)存消耗,也同時減少了?戶加載時間,優(yōu)化?戶體驗。

生命周期

引用掘金圖片如下:

獲取props

vue2在script代碼塊可以直接獲取props,vue3通過setup指令傳遞

vue2:console.log('props',this.xxx)
vue3:setup(props,context){ console.log('props',props) }

數(shù)據(jù)和方法的定義

Vue2使?的是選項類型API(Options API),Vue3使?的是合成型API(Composition API)

Vue2:

data() { return {}; }, methods:{ }

Vue3:

數(shù)據(jù)和?法都定義在setup中,并統(tǒng)?進?return{}

給父組件傳值emit

vue2:this.$emit()
vue3:setup(props,context){context.emit()}

watchEffect

Vue3中除了watch,還引入了副作用監(jiān)聽函數(shù)watchEffect,用過之后我發(fā)現(xiàn)它和React中的useEffect很像,只不過watchEffect不需要傳入依賴項。

那么什么是watchEffect呢?

watchEffect它會立即執(zhí)行傳入的一個函數(shù),同時響應(yīng)式追蹤其依賴,并在其依賴變更時重新運行該函數(shù)。

computed和watch所依賴的數(shù)據(jù)必須是響應(yīng)式的。

Vue3引入了watchEffect,watchEffect 相當于將 watch 的依賴源和回調(diào)函數(shù)合并,當任何你有用到的響應(yīng)式依賴更新時,該回調(diào)函數(shù)便會重新執(zhí)行。

不同于 watch的是watchEffect的回調(diào)函數(shù)會被立即執(zhí)行,即({ immediate: true })。

組件通信

注意

props中數(shù)據(jù)流是單項的,即子組件不可改變父組件傳來的值

在組合式API中,如果想在子組件中用其它變量接收props的值時需要使用toRef將props中的屬性轉(zhuǎn)為響應(yīng)式。

attrs和listeners

子組件使用$attrs可以獲得父組件除了props傳遞的屬性和特性綁定屬性 (class和 style)之外的所有屬性。

子組件使用$listeners可以獲得父組件(不含.native修飾器的)所有v-on事件監(jiān)聽器,在Vue3中已經(jīng)不再使用;

但是Vue3中的attrs不僅可以獲得父組件傳來的屬性也可以獲得父組件v-on事件監(jiān)聽器

路由

vue3和vue2路由常用功能只是寫法上有些區(qū)別:

vue3的beforeRouteEnter作為路由守衛(wèi)的示例是因為它在setup語法糖中是無法使用的;

大家都知道setup中組件實例已經(jīng)創(chuàng)建,是能夠獲取到組件實例的。

beforeRouteEnter是再進入路由前觸發(fā)的,此時組件還未創(chuàng)建,所以是無法用在setup中的;如果想在setup語法糖中使用則需要再寫一個script 如下:

<script>
export default {
  beforeRouteEnter(to, from, next) {
    // 在渲染該組件的對應(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) {
    // 在渲染該組件的對應(yīng)路由被 confirm 前調(diào)用
    next()
  },
  beforeRouteLeave ((to, from, next)=>{//離開當前的組件,觸發(fā)
    next()       
  }),
  beforeRouteLeave((to, from, next)=>{//離開當前的組件,觸發(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) {
    // 在渲染該組件的對應(yīng)路由被 confirm 前調(diào)用
    next()
  },
  beforeRouteEnter (to, from, next) {
    // 在渲染該組件的對應(yīng)路由被 confirm 前調(diào)用
    next()
  },
  beforeRouteLeave ((to, from, next)=>{//離開當前的組件,觸發(fā)
    next()       
  }),
  beforeRouteLeave((to, from, next)=>{//離開當前的組件,觸發(fā)
    next()      
  }),
  methods:{
    toPage(){
      //路由跳轉(zhuǎn)
      this.$router.push(xxx)
    }
  },
  created(){
    //獲取params
    this.$route.params
    //獲取query
    this.$route.query
  }
}
</script>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容