vue3.0基礎語法總結

語言: CN / TW / HK

vue3.0基礎語法總結

#### 前言 大家好!我叫椰_季,是一個剛入行不久得前端工程師,本著在提升自我學習能力為前提和認識一些前端方面得朋友為主要任務。準備釋出一篇自己學習vue3.0基礎語法的總結。學習途徑來源於B站張天禹老師。

### vue2.0的一些缺陷 我們先來說一說vue2.0存在的一些缺陷,大家都知道vue2.0中資料的代理方式是使用的defineProperty來實現響應式的。那麼defineProperty存在什麼樣的問題呢 - 不能監聽陣列的變化

  • 必須遍歷物件的每個屬性

  • 必須深層遍歷巢狀的物件

  • 1、資料規模是否龐大。建立Vue例項的時候,一旦物件是一個深層的引用(老千層餅了),遞迴進行Observer的建立顯然會花很多時間;

    2、對所有屬性的變化進行監聽,也需要消耗不小的記憶體;

    3、新增/刪除屬性的時候,怎麼呼叫/解除安裝defineProperty;

    4、vue2的官方文件,對開發者說明了defineProperty的一些限制,比如說陣列在兩種情況下是無法監聽的:

    1、利用索引直接設定一個數組項時,例如:arr[indexOfItem] = newValue;

    2、修改陣列的長度時,例如:arr.length = newLength;

當我們的專案需求變得更復雜時,watch,computed,inject,provide等配置,這個.vue檔案也會逐漸增大

as.awebp 以上圖片來源於花果山大聖,具體瞭解v2的option以及v3的composition,參考大聖這篇文章

vue3給我們帶來了什麼

一、效能的提升

  • 打包大小減少了41%
  • 初次渲染快55%, 更新渲染快133%
  • 記憶體減少54%

二、原始碼的升級

  • 使用Proxy代替defineProperty實現響應式
  • 重寫虛擬DOM的實現和Tree-Shaking

三、擁抱TypeScript

  • Vue3可以更好的支援TypeScript

四、一些新特性 Composition API(組合API)

  • setup

1、setup是Vue3.0中一個新的配置項,值為一個函式,setup是所有Composition API(組合API)表演的舞臺

2、元件中所用到的:資料、方法等等,均要配置在setup中

3、若返回一個物件,則物件中的屬性、方法, 在模板中均可以直接使用

1.png 此處需要將setup 中定義的值 return 返回出去,模板中才能使用

4、setup的一些注意點:

  1、在vue3中是可以繼續使用vue2中的語法的,但是官方不推薦這樣使用。 
  2、Vue2.x配置(data、methos、computed...)中可以訪問到setup中的屬性、方法。但在setup中不能訪問到Vue2.x配置(data、methos、computed...)。
  3、如果有重名, setup優先。
  4、setup執行的時機,在beforeCreate之前執行一次,this是undefined
  5、setup的引數:
      props:值為物件,包含:元件外部傳遞過來,且元件內部宣告接收了的屬性
      context:上下文物件
          attrs: 值為物件,包含:元件外部傳遞過來,但沒有在props配置中宣告的屬性, 相當於 `this.$attrs`
          slots: 收到的插槽內容, 相當於 `this.$slots`
          emit: 分發自定義事件的函式, 相當於 `this.$emit`
  • ref

    ref是用來定義一個響應式的資料,需要先import 結構引入ref,需要定義的值用ref進行一個包裹

2.png

3.png

  • reactive

    作用:定義一個物件型別的響應式資料(基本型別不要用它,要用ref函式)

語法:const 代理物件 = reactive(源物件)接收一個物件(或陣列),物件(proxy物件) reactive定義的響應式資料是 深層次的 內部基於ES6的 Proxy實現,通過代理物件操作源物件內部資料進行操作

`

//reactvie處理物件是深層次的
let job2 = reactive({
  type:'php',
  salary:'40k'
})

let hobby = reactive(['吃飯','睡覺','寫程式碼'])

function change(){
  // name.value = "李四"
  // age.value = 20
  // job.value.type = "java工程師"
  // job.value.salary = "30k"

  // // 如果建立的物件是通過reactive建立的,那麼修改直接通過物件.裡面的屬性就好,不需要像ref那樣 多加一層.value
  // job2.type = "go開發"
  // job2.salary = "60k"
  // console.log(name,age,job.value);

  // 在vue3中 可以直接通過 這樣修改
  hobby[0] = '學習'
}

` - #### reactive對比ref - 從定義資料角度對比:

-   ref用來定義:**基本型別資料**。
-   reactive用來定義:**物件(或陣列)型別資料**。
-   備註:ref也可以用來定義物件(或陣列)型別資料, 它內部會自動通過`reactive`轉為**代理物件**。
  • 從原理角度對比:

    • ref通過Object.defineProperty()getset來實現響應式(資料劫持)。
    • reactive通過使用Proxy來實現響應式(資料劫持), 並通過Reflect操作源物件內部的資料。
  • 從使用角度對比:

    • ref定義的資料:操作資料需要.value,讀取資料時模板中直接讀取不需要.value
    • reactive定義的資料:操作資料與讀取資料:均不需要.value
  • computed

    與Vue2.x中computed配置功能一致
    

    `

    import { reactive, computed } from "vue"; setup() { let person = reactive({ name: "張三", finame: "狂徒", });

    // 計算屬性的簡寫形式,是隻讀的沒有考慮修改 // person.quanc = computed(() => { // return person.name + "-" + person.finame; // }); person.quanc = computed({ get() { // 使用者讀取資料 return person.name + "-" + person.finame; }, set(value) { // 這裡獲取的value是有 - 的 通過擷取-將值拆分成陣列,然後再進行 索引的第0 和第 1 個獲得對應的姓 和名 const qwe = value.split("-"); person.name = qwe[0]; person.finame = qwe[1]; }, }); return { person, }; },

`

  • watch

    與Vue2.x中watch配置功能一致

``` //情況一:監視ref定義的響應式資料 watch(sum,(newValue,oldValue)=>{ console.log('sum變化了',newValue,oldValue) },{immediate:true})

//情況二:監視多個ref定義的響應式資料 watch([sum,msg],(newValue,oldValue)=>{ console.log('sum或msg變化了',newValue,oldValue) })

/ 情況三:監視reactive定義的響應式資料 若watch監視的是reactive定義的響應式資料,則無法正確獲得oldValue!! 若watch監視的是reactive定義的響應式資料,則強制開啟了深度監視 / watch(person,(newValue,oldValue)=>{ console.log('person變化了',newValue,oldValue) },{immediate:true,deep:false}) //此處的deep配置不再奏效

//情況四:監視reactive定義的響應式資料中的某個屬性 watch(()=>person.job,(newValue,oldValue)=>{ console.log('person的job變化了',newValue,oldValue) },{immediate:true,deep:true})

//情況五:監視reactive定義的響應式資料中的某些屬性 watch([()=>person.job,()=>person.name],(newValue,oldValue)=>{ console.log('person的job變化了',newValue,oldValue) },{immediate:true,deep:true})

//特殊情況 watch(()=>person.job,(newValue,oldValue)=>{ console.log('person的job變化了',newValue,oldValue) },{deep:true}) //此處由於監視的是reactive素定義的物件中的某個屬性,所以deep配置有效

如果都是利用ref建立的,利用watch來監視的話。基本型別的值 直接在第一個引數內傳入定義的變數名。 如果是物件型別的話: 一、可以在變數名的後方加上.value 那麼v3中他內部會藉助reactive 來實現深層次監聽。 二、可以不新增.value ,可以在第三個引數內加上deep:true也可以開啟深度監聽

```

  • watchEffect

watch的套路是:既要指明監視的屬性,也要指明監視的回撥 watchEffect的套路是:不用指明監視哪個屬性,監視的回撥中用到哪個屬性,那麼它就監視哪個屬性

watchEffect有點像computed: 但是computed注重的是計算出來的值(回撥函式的返回值),所以必須要寫返回值 而watchEffect更注重的是過程(回撥函式的函式體),所以不用寫返回值

``` import { ref, watch, reactive, watchEffect } from "vue";

setup() { let qwe = ref(0); let www = ref("你哈"); let person = reactive({ name: "張三", age: 18, fn: { j1: { st: 20, }, }, });

//watchEffect所指定的回撥中用到的資料只要發生變化,則直接重新執行回撥。
watchEffect(() => {
  let f1 = qwe.value;
  let f2 = person.fn.j1.st;
  console.log("haha");
});

return {
  qwe,
  www,
  person,
};

}, }

```

  • toRefs

    toRefs建立一個 ref 物件,其value值指向另一個物件中的某個屬性。

```

setup(){ //資料 let person = reactive({ name:'張三', age:18, job:{ j1:{ salary:20 } } })

    const x = toRefs(person)
console.log('******',x)

//返回一個物件(常用)
    // 一般我們要將響應式物件中的某個屬性單獨提供給外部使用時使用toRef
return {
  person,
  // name:toRef(person,'name'),
  // age:toRef(person,'age'),
  // salary:toRef(person.job.j1,'salary'),
  ...toRefs(person)
}
}

}

```

五、新的內建元件

  • Fragment
    -   在Vue2中: 元件必須有一個根標籤
    -   在Vue3中: 元件可以沒有根標籤, 內部會將多個標籤包含在一個Fragment虛擬元素中
    -   好處: 減少標籤層級, 減小記憶體佔用
    
    • Teleport

      • 主要就是用在類似遮罩彈框這種,可以在子元件控制邏輯,但是DOM物件卻是在body下的這種效果,能夠將我們的元件html結構移動到指定位置的技術。
      • Teleport就是一種將程式碼組織邏輯依舊放在元件中,這樣我們能夠使用元件內部的資料狀態,控制組件展示的形式,但是最後渲染的地方可以是任意的,而不是侷限於元件內部

```

我是一個彈窗

```

  • Suspense - 等待非同步元件時渲染一些額外內容,讓應用有更好的使用者體驗 - 非同步引入元件

    import {defineAsyncComponent} from 'vue' const Child = defineAsyncComponent(()=>import('./components/Child.vue'))

  • 使用Suspense包裹元件,並配置好default 與 fallback

<template> <div class="app"> <h3>我是App元件</h3> <Suspense> <template v-slot:default> <Child/> </template> <template v-slot:fallback> <h3>載入中.....</h3> </template> </Suspense> </div> </template>

總結

學習是一輩子的事,不光指學習計算機技術,生活的方方面面都需要保持一個學習的心,祝大家學習愉快。 第一次總結寫文章,文中如有錯誤,歡迎碼友在評論區指正。

「其他文章」