效能提升(零成本:從vue2切到vue3就享受到)
首次渲染更快,diff演演算法更快,記憶體佔用更少,打包體積更小,....
更好的Typescript支援(在vue下寫TS更方便了)
提供新的寫程式碼的方式:Composition API
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"/>
主要看三個位置:
package.json
main.js
app.vue
首先我們可以看一下package.json
檔案,在dependencies設定項中顯示,我們當前使用的版本為3
"dependencies": { "core-js": "^3.6.5", "vue": "^3.2.25" // 版本號 }
然後開啟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發現:vue3.0的單檔案元件中不再強制要求必須有唯一根元素
<template> <img alt="Vue logo" src="./assets/logo.png"> <HelloWorld msg="Welcome to Your Vue.js App"/> </template>
組合式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) 優點:功能程式碼組合維護, 方便功能複用;
setup 函數是一個新的元件選項,作為元件中組合式API 的起點(入口)
setup 中不能使用 this, this 指向 undefined
setup函數只會在元件初始化的時候執行一次
setup函數在beforeCreate生命週期勾點執行之前執行
setup() { console.log('setup....', this) }, beforeCreate() { console.log('beforeCreate') // 它比setup遲 }
setup 引數:
使用setup 時,它接受兩個引數:
返回值
這個函數的返回值是一個物件,在模版中需要使用的資料和函數,需要在這個物件中宣告(如果在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發射事件。並且這幾個屬性都是自動同步最新的值,所以我們每次使用拿到的都是最新值。
在 vue2.x 中, 定義資料都是在data中, 但是 Vue3.x 可以使用 reactive 和 ref 來進行資料定義。
如何取捨ref和reactive?
定義響應式資料有兩種方式:
ref函數(可以處理簡單資料,也可以處理複雜資料),常用於將簡單資料型別定義為響應式資料
在程式碼中修改(或者獲取)值時,需要補上.value
在模板中使用時,可以省略.value
reactive函數,常用於將複雜資料型別為響應式資料
推薦用法:
優先使用ref
如果明確知道物件中有什麼屬性,就使用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>
增強版的結構賦值:在解構物件的同時,保留響應式的特點。
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) }) }, });
格式:
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>
總結:
計算屬性兩種用法
給computed傳入函數,返回值就是計算屬性的值
給computed傳入物件,get獲取計算屬性的值,set監聽計算屬性改變
在v-model繫結計算屬性: <input v-model="total" />
基於響應式資料的變化執行回撥邏輯,和vue2中的watch的應用場景完全一致。
步驟:
匯入 import { watch } from 'vue'
開啟監聽。在setup函數中執行watch函數開啟對響應式資料的監聽
watch函數接收三個常規引數 watch(source, callback, [options])
第一個引數有三種取值:
物件,要監聽的響應式資料
陣列,每個元素是響應式資料
函數,返回你要監聽變化的響應式資料
第二個引數是:響應式資料變化之後要執行的回撥函數
第三個引數是: 一個物件,在裡面設定是否開啟立刻執行或者深度監聽
<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其它相關文章!