1. 程式人生 > 其它 >不一樣的vue3:setup函式篇

不一樣的vue3:setup函式篇

不一樣的vue3.0:setup函式

感慨

2020.9.18日正式釋出,過去已有幾個月時間但很多文章都是有錯誤內容的引導。相信也有很多人感受到。目前主要講setup函式官方文件

新的改變之setup函式

vue2.x版本功能太散亂造成維護難、可讀性也差,更改或者查詢需要不停的跳轉,在vue3.0的改變中改變了這一糟糕的操作:

  1. 組合式API的入口函式setup ,將會帶來全新的程式碼編寫體驗;
    先了解setup的執行時機,官方文件setup的第一句話說了新的 setup元件選項在建立元件之前執行,也就是說setup函式執行的時侯生命週期還沒開始執行 讓我們嘗試一下:
  setup(){
    console.log('setup執行了');
  }
  beforeCreate(){
    console.log('beforeCreate執行了');
  },
  created () {
    console.log('create執行了');
  },

我們會得到想象中一樣的結果,執行這個是為了打破其他文章中所說的setup函式是在beforeCreate和created之間執行的謠言:
在這裡插入圖片描述
需要注意的是
由於在執行 setup 時,元件例項尚未被建立,因此在 setup 選項中沒有 this。這意味著,除了 props 之外,你將無法訪問元件中宣告的任何屬性——本地狀態、計算屬性或方法。

這句話很好理解就不再多做解釋。

宣告變數:
如果在setup函式中宣告響應式的變數vue3.0給我們提供了ref和reactive方法
使用起來很簡單:
首先引入ref和reactive函式
在setup函式中宣告的變數和方法我們想使用的話需要return出去

import { ref, reactive } from 'vue';
export default {
 setup(){
  const num=ref(0);
  const obj=reactive({age:20})
  return {num.obj}
 }
}

return這一步做了啥,暴露出去的變數和方法其實是在相應的data和methods裡注入了,為什麼這麼說,實驗一下:

  setup(){
   const num=ref(0);
   const obj=reactive({age:20})
   return {num,obj}
  }
  beforeCreate(){
  },
  created () {
    //在options選項中的creat生命週期通過this列印一下
    //num和obj.age
    console.log(this.num)
    console.log(this.obj.age)
  },

列印得到:
在這裡插入圖片描述
如果在setup中點選某個按鈕修改ref建立的變數值是基本型別時正確的方式:例如num.value=6

如果是修改ref建立的變數值是引用型別時正確的方式:例如obj.value.age=18

//空間有限就不寫重複程式碼
setup(){
  function addNum(){
    num.value=6
  }
  return {addNum}
}

當你用ref和reactive建立引用型別時,會對變數的每一層級用proxy代理
怎麼驗證這一說法://

setup(){
  const count=ref({1:0});
  const logObj=reactive({
     a:'zhe',
     aa:{
      b:'hen',
      bb:{
       c:'棒',
       cc:{
        d:'呀'
       }
      }
     }
  })
   console.log(count.value)
   console.log(logObj.aa);
   console.log(logObj.aa.bb);
   console.log(logObj.aa.bb.cc);
  return {count,logObj}
}

列印得到:
在這裡插入圖片描述
注意當使用ref建立引用型別時會伴隨著鏈式,因為沒對一個物件或陣列操作都會xxx.value.xx,在建立引用型別建議使用reactive建立, reactive引數必須是物件或陣列,否則無法更新檢視

既然ref和reactive會監聽每一層的變化就少不了效能的消耗,但這不是我們考慮,畢竟沒有在專案開發無法得到真實消耗

介紹shallowRef和shallowReactive
這兩個方法使用方法跟ref和reactive一樣;
不同的是效果

 setup(){
  const count=shallowRef({a:0});
  const obj = shallowReactive({
      a: 1,
      aa: {
        b: 2,
        bb: {
          c: 3
        }
      }
    })
    console.log(count.value)

    console.log(obj)
    console.log(obj.aa)
    console.log(obj.aa.bb);
  return {}
 }

列印:
在這裡插入圖片描述
這是obj的列印結果,可以看到使用shallowReactive方法建立只會對第一層資料proxy代理,
為什麼沒截count的列印結果,這裡需要單獨解答,使用shallowRef方法建立的變數只有value的引用關係發生變化才會更新檢視
這就使得shallow比較low,也可能是針對特定的場景使用

那麼有沒有既不針對每一層進行proxy代理又不像shallow這樣的呢?我想某個值發生變化也觸發響應式變化

vue也提供了方法他需要你在改變了資料之後主動觸發
triggerRef( 變數名 )

setup(){
const shalowObj = shallowRef({
      a: 1,
      aa: {
        b: 2,
        bb: {
          c: 3
        }
      }
    })
  function changeObj(){
    shalowObj.value.aa.bb.c=4;
    triggerRef(shalowObj)
  }
}

但是vue沒有提供triggerReactive方法「 吐血 」

setup函式中可以註冊生命週期,偵聽器,計算屬性等 生命週期:選項式API為 mounted,那麼組合式上的生命週期函式為onMounted,字首為 on,這些函式接受一個回撥,當鉤子被元件呼叫時,該回調被執行

setup(){
onMounted(changeObj)//在mounted生命週期中呼叫changeObj
}

偵聽器:接受三個引數,一-想要偵聽的響應式引用或者getter函式,二-回撥,三-可選的配置選項

watch(shalowObj, (newValue, oldValue) => { console.log('偵聽到了shalowObj變化'); })

計算屬性:

const computedCount =computed(() => num.value * 2)

還有需要注意的是setup函式本身不能非同步

async setup(){
//這是錯誤的
}

setup簡單的介紹就到這裡吧!!!再見
如有錯誤,請把我糾正,讓我迷途知返,讓我迷途知返,讓我迷途知返

感謝!!!