您好,登錄后才能下訂單哦!
本篇內容主要講解“Vue3.0新特性怎么使用”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Vue3.0新特性怎么使用”吧!
性能提升(零成本:從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 時,它接受兩個參數:
props: props為一個對象,內部包含了父組件傳遞過來的所有prop數據
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發射事件。并且這幾個屬性都是自動同步最新的值,所以我們每次使用拿到的都是最新值。
在 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>
到此,相信大家對“Vue3.0新特性怎么使用”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。