Vue3.0新特性以及使用總結(整理分享)

2022-01-28 19:01:03
本篇文章給大家分享vue3.0的新特性以及使用總結,起鬨包括一些新變化,以及哪些以前的語法不能用了,希望對大家有幫助。

1、Vue3帶來的新變化

  1. 效能提升(零成本:從vue2切到vue3就享受到)

    首次渲染更快,diff演演算法更快,記憶體佔用更少,打包體積更小,....

  2. 更好的Typescript支援(在vue下寫TS更方便了)

  3. 提供新的寫程式碼的方式:Composition API

2、這些Vue2.0的語法不能用了

vue3.0對於2.0版本的大部分語法都是可以相容的(之前是怎麼寫的,現在也正常寫),但是也有一些破壞性的語法更新,這個要格外注意:

1、移除了vue範例上的$on方法 (eventBusVue.prototype.$eventBus=new Vue(); this.$on('事件名', 回撥)現有實現模式不再支援,可以使用三方外掛替代)。下邊是vue2中eventBus的用法:

Vue.prototype.$eventBus = new Vue()
元件1
this.$on('事件名', 回撥)
元件2
this.$emit('事件名')

2、移除過濾器選項 。下邊是vue2中過濾器的用法:

<p>{{ msg | format}}</p>
插值表示式裡, 不能再使用過濾器filter, 可以使用methods替代
{{format(msg)}}

3、移除 .sync語法(v-bind時不能使用.sync修飾符了,現在它v-model語法合併了)。下面是vue2中.sync的用法

<el-dialog :visibel.sync="showDialog"/>

3、vue2和3的專案區別

主要看三個位置:

  1. package.json

  2. main.js

  3. app.vue

package.json

首先我們可以看一下package.json檔案,在dependencies設定項中顯示,我們當前使用的版本為3

"dependencies": {
    "core-js": "^3.6.5",
    "vue": "^3.2.25"  // 版本號
}

main.js

然後開啟main.js 入口檔案,發現Vue的範例化發生了一些變化,由先前的new關鍵詞範例化,轉變為createApp方法的呼叫形式 。

vue2.x中的寫法:

import Vue from 'vue'
import App from './App.vue'
new Vue({render: h => h(App)}).$mount('#app')

vue3.x的寫法:

import { createApp } from 'vue'
import App from './App.vue' // 根元件
createApp(App).mount('#app')

app.vue

開啟app.vue發現:vue3.0的單檔案元件中不再強制要求必須有唯一根元素

<template>
  <img alt="Vue logo" src="./assets/logo.png">
  <HelloWorld msg="Welcome to Your Vue.js App"/>
</template>

4、組合式API和選項式API

組合式api(Composition API)是vue3對我們開發者來說變化非常大的更新。

Vue2 選項式API,options API (如圖) , Vue3 組合式API, composition API (右圖):

Vue2 選項式API,options API:

優點:

理解容易,好上手。因為各個選項(設定項)都有固定的書寫位置(比如資料就寫到data選項中,操作方法就寫到methods中,等等)

缺點:

應用大了之後,相信大家都遇到過來回上下找程式碼的困境-----橫跳。

Vue3 組合式API, composition API :

特點:

  • 特定功能相關的所有東西都放到一起維護,比如功能A相關的響應式資料,運算元據的方法等放到一起,這樣不管應用多大,都可以快速定位到某個功能的所有相關程式碼,維護方便設定

  • 如果功能複雜,程式碼量大,我們還可以進行邏輯拆分處理。

總結:

組合式API的由來。由於vue3中提供了一個新的寫程式碼的方式(老方式也是可以使用的),為了區別vue2,給他們各自取了不同的名字:

Vue2選項式API(option api) 優點:簡單,各選項各司其職;缺點:不方便功能複用;功能程式碼分散維護程式碼橫跳

Vue3組合式API(composition api) 優點:功能程式碼組合維護, 方便功能複用;

4、setup

  1. setup 函數是一個新的元件選項,作為元件中組合式API 的起點(入口)

  2. setup 中不能使用 this, this 指向 undefined

  3. setup函數只會在元件初始化的時候執行一次

  4. setup函數在beforeCreate生命週期勾點執行之前執行

setup() {
	console.log('setup....', this)
},
beforeCreate() {
	console.log('beforeCreate') // 它比setup遲
}

setup 引數:

使用setup 時,它接受兩個引數:

  1. props: props為一個物件,內部包含了父元件傳遞過來的所有prop資料
  2. context: context物件包含了attrs,slots, emit屬性

返回值

這個函數的返回值是一個物件,在模版中需要使用的資料和函數,需要在這個物件中宣告(如果在data()中也定義了同名的資料,則以setup()中為準)。

<template>
  <p class="container">
    姓名:{{name}},月薪:{{salary}} <button @click="say">打個招呼</button>
  </p>
</template>
<script>
export default {
  setup () {
    console.log('setup執行了,這裡沒有this. this的值是:', this)

    // 定義資料和函數
    const name = '小吳'
    const salary = 18000
    const say = () => {
      console.log('我是', name)
    }

    // 返回物件,給檢視使用
    return { msg , say}
  },
  beforeCreate() {
    console.log('beforeCreate執行了, 這裡有this,this的值是:',  this)
  }
}
</script>

setup 中接受的props是響應式的, 當傳入新的 props 時,會及時被更新。由於是響應式的, 所以不可以使用 ES6 解構,解構會消除它的響應式。 錯誤程式碼範例, 這段程式碼會讓 props 不再支援響應式:

export default com ({
    setup(props, context) {
        const { uname } = props
        console.log(uname)
    },
})

開發中我們想要使用解構,還能保持props的響應式,有沒有辦法解決呢?setup接受的第二個引數context,我們前面說了setup中不能存取 Vue2 中最常用的this物件,所以context中就提供了this中最常用的三個屬性:attrs、slot 和emit,分別對應 Vue2.x 中的 $attrs屬性、slot 插槽 和$emit發射事件。並且這幾個屬性都是自動同步最新的值,所以我們每次使用拿到的都是最新值。

5、reactive、ref 與 toRefs

在 vue2.x 中, 定義資料都是在data中, 但是 Vue3.x 可以使用 reactive 和 ref 來進行資料定義。

如何取捨ref和reactive?

定義響應式資料有兩種方式:

  • ref函數(可以處理簡單資料,也可以處理複雜資料),常用於將簡單資料型別定義為響應式資料

    • 在程式碼中修改(或者獲取)值時,需要補上.value

    • 在模板中使用時,可以省略.value

  • reactive函數,常用於將複雜資料型別為響應式資料

推薦用法:

  1. 優先使用ref

  2. 如果明確知道物件中有什麼屬性,就使用reactive。例如,表單資料

接下來使用程式碼展示一下 ref、reactive的使用:

<template>
  <p class="container">
    <p>{{ num }}</p>
    <p>姓名: {{ user.uname }}</p>
    <p>年齡: {{ user.age }}</p>
  </p>
</template>

<script>
import { reactive, ref, toRefs } from "vue";
export default com({
  setup() {
    const num = ref(0);
    const user = reactive({ uname: "vivian", age: 18});
    setInterval(() => {
      num.value++;
      user.age++;
    }, 1000);
    return {
      year,
      user
    };
  },
});
</script>

上面的程式碼中,我們繫結到頁面是通過user.uname,user.age這樣寫感覺很繁瑣,我們能不能直接將user中的屬性解構出來使用呢? 答案是不能直接對user進行結構,這樣會消除它的響應式,這裡就和上面我們說props不能使用 ES6 直接解構就呼應上了。那我們就想使用解構後的資料怎麼辦,解決辦法就是使用toRefs,定義轉換響應式中所有屬性為響應式資料,通常用於解構|展開reactive定義物件, 簡化我們在模板中的使用。

格式:

// 響應式資料:{ 屬性1, 屬性2 }
let { 屬性1, 屬性2 } = toRefs(響應式資料)

具體使用方式如下:

<template>
  <p class="container">
    <p>{{ num }}</p>
    <p>姓名: {{ uname }}</p>
    <p>年齡: {{ age }}</p>
  </p>
</template>

<script>
import { defineComponent, reactive, ref, toRefs } from "vue";
export default com({
  setup() {
    const num = ref(0);
    const user = reactive({ uname: "vivian", age: 18});
    setInterval(() => {
      num.value++;
      user.age++;
    }, 1000);
    return {
      year,
      // 使用reRefs
      ...toRefs(user),
    };
  },
});
</script>

增強版的結構賦值:在解構物件的同時,保留響應式的特點。

6、vue3.0生命週期勾點函數

  • setup建立範例前

  • onBeforeMount掛載DOM前

  • onMount掛載DOM後

  • BeforeUpdate 更新元件前

  • updated 更新元件後

  • onBeforeUnmount解除安裝銷燬前

  • onUnmount 解除安裝銷燬後

setup () {
    onBeforeMount(()=>{
      console.log('DOM渲染前',document.querySelector('.container'))
    })
    onMounted(()=>{
      console.log('DOM渲染後1',document.querySelector('.container'))
    })
  }

Vue3.x 還新增用於偵錯的勾點函數onRenderTriggered和onRenderTricked, 另外,Vue3.x 中的勾點是需要從 vue 中匯入的:

import { defineComponent, onBeforeMount, onMounted, onBeforeUpdate,onUpdated,
onBeforeUnmount, onUnmounted, onErrorCaptured, onRenderTracked,onRenderTriggered } from "vue"; 
export default defineComponent({ 
//beforeCreate和created是vue2的 
beforeCreate() {
console.log("--beforeCreate--")
 }, 
created() {
console.log("--created--")
 }, 
setup() { 
console.log("--setup--")
// vue3.x生命週期寫在setup中 
onBeforeMount(() => {
console.log("--onBeforeMount--")
})
onMounted(() => {
console.log("--onMounted--"); })
 // 偵錯哪些資料發生了變化
onRenderTriggered((event) =>{ 
console.log("--onRenderTriggered--",event)
}) 
}, 
});

7、computed函數定義計算屬性

格式:

import { computed } from 'vue'

const 計算屬性名 = computed(() => {
  return 相關計算結果
})

程式碼範例:

<template>
  <p>姓名:{{name}}, 公司:{{company}}, 月薪:{{salary}}, 年薪{{total}}</p>
  <button @click="double">月薪double</button>
</template>
<script>
import { ref, computed } from 'vue'
export default {
  name: 'App',
  setup () {
    // 定義響應式物件
    const company = ref('DiDi')
    const name = ref('小王')
    const salary = ref(18000)
    const double = () => {
      salary.value *= 2 // ref資料要加.value
    }
    // 定義計算屬性
    const total = computed(() => 12 * salary.value)
    
    return {  
      name, 
      company,
      total,
      salary,
      double
    }
  }
}
</script>

總結:

vue3中的computed函數與vue2中的computed選項功能類似。

computed的入參是一個函數

作用:根據已有資料,產生新的響應式資料。

步驟:匯入,定義,匯出

computed的高階用法:

格式:

const 計算屬性 =  computed({
  get () {
    // 當獲取值自動呼叫
  },
  set (val) {
    // 當設定值自動呼叫,val會自動傳入
  }
})

範例程式碼:

<template>
  <p style="padding:2em">
    <p>小花, 月薪:{{salary}}, 年薪:{{total}}</p>
    <p>年薪:<input v-model="total"/></p>
    <button @click="double">月薪double</button>
  </p>
</template>
<script>
// reactive: 是除了ref之外的第二種申明響應式資料的方式

import { ref, computed } from 'vue'
export default {
  setup () {
  
    const salary = ref(18000)
     
    const double = () => {
      salary.value *= 2
      console.log(salary)
    }
    // 定義計算屬性: 普通的寫法:只使用了get
    // const total = computed(() => {
    //   return stu.salary * 12
    // })

    // 定義計算屬性: 高階的寫法:使用了get + set
    const total = computed({
      get() { return salary.value * 12 },
      set(val) { 
        // 設定計算屬性的值,會自動呼叫,並傳入val
        console.log('要設定的值...', val)
        salary.value = val/12
      }
    })
    
    return { double, salary, total}
  }
}
</script>

總結:

計算屬性兩種用法

  1. 給computed傳入函數,返回值就是計算屬性的值

  2. 給computed傳入物件,get獲取計算屬性的值,set監聽計算屬性改變

  3. 在v-model繫結計算屬性: <input v-model="total" />

8、watch函數

基於響應式資料的變化執行回撥邏輯,和vue2中的watch的應用場景完全一致。

步驟:

  1. 匯入 import { watch } from 'vue'

  2. 開啟監聽。在setup函數中執行watch函數開啟對響應式資料的監聽

  3. watch函數接收三個常規引數 watch(source, callback, [options])

    1. 第一個引數有三種取值:

      物件,要監聽的響應式資料

      陣列,每個元素是響應式資料

      函數,返回你要監聽變化的響應式資料

    2. 第二個引數是:響應式資料變化之後要執行的回撥函數

    3. 第三個引數是: 一個物件,在裡面設定是否開啟立刻執行或者深度監聽

<template>
    <p>
        {{stu}}, {{salary}}
        <button @click="doSome"> do</button>
    </p>
</template>
<script>
import { reactive, watch, ref } from 'vue'
export default {
    setup() {
        const salary = ref(10000)
        const stu  = reactive({
            address: {city: 'wuhan'}
        })

        // 1. 偵聽-單個資料
        watch(salary, (newVal, oldVal) => {
            console.log('監聽單個資料', newVal, oldVal)
        })
			 // 偵聽-單個資料
        watch(stu, (newVal, oldVal) => {
            console.log('監聽單個資料', newVal, oldVal)
        })

      	// 偵聽-多個資料
        watch([stu, salary], (newVal, oldVal) => {
            console.log('監聽多個資料', newVal, oldVal)
        })
				// 偵聽物件的某個屬性
        watch(()=>stu.address , (newVal, oldVal) => {
            console.log('第一個引數是函數', newVal, oldVal)
        }, {deep: true,  immediate: true} )

        // 測試按鈕,修改資料
        const doSome = () => {
            salary.value +=1
            stu.address.city = ''
        }

        return {stu, salary, doSome}
    }
}
</script>

總結:

作用:watch用來偵聽資料的變化。

格式:watch(資料|陣列|get函數,(新值,舊值)=>{回撥處理邏輯}, {immediate:true|false, deep: true|false})

以上,我們瞭解了vue2和vue3使用方法的不同,關於元件通訊和插槽等可以看下一篇。

【相關推薦:《》】

以上就是Vue3.0新特性以及使用總結(整理分享)的詳細內容,更多請關注TW511.COM其它相關文章!