vue2和vue3區別


1、ref 的使用

v-for 中的 Ref 數組 | Vue.js (vuejs.org)

2、$children

$children | Vue.js (vuejs.org)

 

$children 實例 property 已從 Vue 3.0 中移除,不再支持。

3、插槽的使用

作用域插槽的寫法

vue2.6以前

<template slot="t3" slot-scope="scope">
    {{scope.data}}
</template>

vue2.6以后

<template v-slot:t3="scope">
    {{scope.data}}
</template>

vue3只支持vue2.6之后的寫法,vue2.6以前的寫法不再支持,且vue3中可以進一步簡化,用#代替v-slot:

<template #t3="scope">
    {{scope.data}}
</template>

4、響應式系統的升級

vue2

Vue2.0中使用ES5中的Object.defineProperty方法實現響應式數據
缺點
無法監測到對象屬性的動態添加和刪除
無法監測到數組的下標和length屬性的變更
解決方案
Vue2.0提供Vue.set方法用於動態給對象添加屬性
Vue2.0提供Vue.delete方法用於動態刪除對象的屬性
重寫vue中數組的方法,用於監測數組的變更

<body>
    <script>
      // vue會做一個數據劫持,,,監視數據的變化,一旦數據變化了,更新DOM
      const data = {
        name: 'zs',
        age: 18
      }
      for (let k in data) {
        let temp = data[k]
        Object.defineProperty(data, k, {
          get() {
            console.log(`我劫持了${k}的獲取`)
            return temp
          },
          set(value) {
            console.log(`我劫持了${k}的設置,值${value}`)
            temp = value
          }
        })
      }
      // Object.defineProperty有缺點
      // 1. 無法監視到新增的屬性的變更和刪除
      // 2. 無法劫持到數組的下標和長度
    </script>
  </body>
  <body>
    <div id="app">
      <h1>vue的例子</h1>
      <p>{{car.brand}} --- {{car.color}} ---{{car.price}}</p>
      <p>{{arr}}</p>
    </div>
    <script src="https://unpkg.com/vue@2.6.12/dist/vue.js"></script>
    <script>
      // vue中需要使用$set方法動態的增加一個響應式屬性
      const vm = new Vue({
        el: '#app',
        data: {
          car: {
            brand: '奔馳',
            color: 'blue'
          },
          arr: ['張三', '李四']
        }
      })
    </script>
  </body>

vue3

通過 Proxy(代理): 攔截對data任意屬性的任意(13種)操作, 包括屬性值的讀寫, 屬性的添加, 屬性的刪除等...
通過 Reflect(反射): 動態對被代理對象的相應屬性進行特定的操作
Vue3.0中使用ES6中的proxy語法實現響應式數據
優點
可以檢測到代理對象屬性的動態添加和刪除
可以監測到數組的下標和length屬性的變更
缺點
ES6的proxy語法對於低版本瀏覽器不支持,IE11
Vue3.0會針對於IE11出一個特殊的版本用於支持ie11

  <body>
  <div></div>
  <script>
    const data = {
      name: 'zs',
      age: 18
    }
    // 能夠監測到對象動態新增的屬性以及刪除的屬性
    // proxy
    const proxyData = new Proxy(data, {
      get(target, name) {
        console.log(`檢測到${name}的獲取`)
        return target[name]
      },
      set(target, name, value) {
        console.log(`檢測到${name}的設置,值為${value}`)
        target[name] = value
      },
      deleteProperty(target, key) {
        console.log(`監測到刪除${key}`)
        return delete target[key]
      }
    })
  </script>
</body>

5、Composition API

5.1 composition-api解決了什么問題

1、使用傳統的option配置方法寫組件的時候問題,隨着業務復雜度越來越高,代碼量會不斷的加大;由於相關業務的代碼需要遵循option的配置寫到特定的區域,導致后續維護非常的復雜,同時代碼可復用性不高,而composition-api就是為了解決這個問題而生的。 

5.2 語法糖介紹

compositon-api提供了一下幾個函數

  • reactive
  • watchEffect
  • computed
  • ref
  • toRefs
  • 生命周期的hooks

5.2.1 reactive

 import { reactive, computed } from 'vue'

  export default {
    setup() {
      const state = reactive({
        count: 0
      })
      
      function increment() {
        state.count++
      }
      
      return {
        state,
        increment
      }
    }
  }

Reactive 相當於當前的 Vue.observable () API,經過reactive處理后的函數能變成響應式的數據,類似於option api里面的data屬性的值。

5.2.2 watchEffect

import { reactive, computed, watchEffect } from 'vue'

export default {
    setup() {
      const state = reactive({
        count: 0
      })

      const double = computed(() => state.count * 2)

      function increment() {
        state.count++
      }

      watchEffect(() => {
        console.log(double.value)
      })
      return {
        state,
        increment
      }
    }
}

Vue 中檢測狀態變化的方法,我們可以在渲染期間使用它。 由於依賴關系跟蹤,當反應狀態發生變化時,視圖會自動更新。 在 DOM 中呈現某些內容被認為是一種“副作用” : 我們的程序在程序本身(DOM)之外修改狀態。 要應用並自動重新應用基於反應狀態的副作用,我們可以使用 watchEffect API。

5.2.3 computed

import { reactive, computed } from 'vue'

export default {
    setup() {
      const state = reactive({
        count: 0
      })
    
      const double = computed(() => state.count * 2)
    
      function increment() {
        state.count++
      }
    
      return {
        state,
        increment
      }
    }
}

有時我們需要依賴於其他狀態的狀態——在 Vue 中,這是通過計算屬性來處理的。 要直接創建一個計算值,我們可以使用computed API。

5.2.4 ref

上面計算屬性返回計算結果是什么? 如果我們猜測一下內部是如何實現 computed 的,我們可能會得出這樣的結論

function computed(getter) {
  let value
  watchEffect(() => {
    value = getter()
  })
  return value
}

但是我們知道這是行不通的: 如果 value 是一個類似 number 的基本類型,那么一旦返回,它與 computed 內部的更新邏輯的連接就會丟失。 這是因為 JavaScript 基本類型是按值傳遞的,而不是按引用傳遞的

當一個值作為屬性分配給一個對象時,同樣的問題也會發生。 如果被賦為屬性或從函數返回時,反應值不能保持其響應性,那么它就沒有多大用處。 為了確保我們總是可以讀取計算的最新值,我們需要將實際

值包裝在一個對象中,然后返回該對象

function computed(getter) {
  const ref = {
    value: null
  }
  watchEffect(() => {
    ref.value = getter()
  })
  return ref
}

所以要拿到ref與computed的值應該是拿返回值下面的value

let count = ref(1)

console.log(count.value) // 1

let double = computed(() => count.value * 2) // 2

值得注意,當我們在template里面使用ref或者computed的時候,vue會自動把它們用reactive處理無需用count.value或者double.value的值,既<div>{{ count }} {{ double }}</div>即可

5.2.5 toRefs

toRefs API提供了一個方法可以把reactive的值處理為ref

5.2.6 生命周期的hooks

你可以通過在生命周期鈎子前面加上 “on” 來訪問組件的生命周期鈎子。

下表包含如何在 setup () 內部調用生命周期鈎子:

注意:因為 setup 是圍繞 beforeCreate 和 created 生命周期鈎子運行的(生命周期執行順序:setup => beforeCreate() => created()),所以不需要顯式地定義它們。換句話說,在這兩個鈎子中編寫的任何代碼都可以(應該)直接在 setup 函數中編寫。

import { onBeforeMount, onMounted, reactive, watchEffect } from 'vue'

export default {
    setup() {
      const state = reactive({
        count: 0
      })

      const double = computed(() => state.count * 2)

      function increment() {
        state.count++
      }

      watchEffect(() => {
        console.log(double.value)
      })
      
      onMounted(() => {
        document.title = 'hello'
      })
      return {
        state,
        increment
      }
    }
}

5.3 最后講講關於使用composition api如何組織代碼

往往是把一個功能的所有狀態、方法、都封裝到一個函數里面,方便統一管理,如果你按照這種方式來寫代碼,那么代碼的結構大致如下

export default {
  setup() { // ...
  }
}

function useCurrentFolderData(networkState) { // ...
}

function useFolderNavigation({ networkState, currentFolderData }) { // ...
}

function useFavoriteFolder(currentFolderData) { // ...
}

function useHiddenFolders() { // ...
}

function useCreateFolder(openFolder) { // ...
}

當我們哪個功能需要在其他組件被復用的時候,直接把相關的方法提取出去,然后再引用進來就可以了

可以看出composition api的面向人群主要是經常寫輪子或者框架的開發者,因為他更靈活,可以寫出高內聚、低耦合的代碼

使用vue3的過程中也不是一定要用composition api的,如果業務不是很復雜使用option api也是沒什么問題的。

composition api和options api可以公用,但是vue3 推薦使用 composition api。

生命周期執行順序:setup => beforeCreate() => created()

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM