對於Vue3和Ts的心得和思考
本文正在參加「金石計劃」
作者:京東物流 吳雲闊
1 前言
Vue3已經正式釋出了一段時間了,各種生態已經成熟。最近使用taro+vue3重構冷鏈的小程式,經過了一段時間的開發和使用,有了一些自己的思考。
總的來說,Vue3無論是在底層原理還是在實際開發過程中,都有了很大的進步。
從原始碼層面來說,使用Proxy代替Object.defineProperty的API,一個是代理的物件,一個是遞迴監控的屬性,從而在效能上有了很大的進步,並且,也解決了物件動態屬性增加、陣列改變監聽上的缺陷;對diff演算法進行優化,增加了靜態標記,大大提高了Vue的執行效率;還有靜態提升、事件監聽快取等一系列提升效率的手段。
從應用層面來說,主要的改變是將option API改成了composition API(組合式API),在業務中拋棄data、methods、生命週期函式隔離開的開發方式,使程式碼相對於業務有更強的聚合性,在程式碼開發、程式碼閱讀、程式碼維護方面對於開發者都是更加友好。
對於typescript有了更好的支援,我們知道,對於大型的前端專案來說,使用typescript的型別校驗,能使前端專案有更強的健壯性,這也使得Vue3對於大型專案的開發提供了更強的質量保證。
2 組合式API
所謂的組合式API,將Vue2中的data、methods、生命週期、資料監聽等option,都封裝成鉤子函式,然後組合到setup函式中,其核心就在於setup函式。setup函式存在的意義,就是為了使用這些新增的組合式API,並且這些API只能在setup函式中使用。
setup函式執行的時機是,props初始化之後,beforeCreate函式執行之前,所以在執行setup時,還沒有初始化Vue例項,因此在setup中不能使用this物件。setup函式的返回值會被注入到Vue例項中,供Vue元件使用,所以任何資料想在Vue元件的模板中使用,必須在setup函式中return出去。
組合式API的組合,體現在兩個層面。第一層的意思是,將某一業務相關資料和處理邏輯放到一起,這是一種關注點的聚合,更方便我們編寫程式碼、處理業務邏輯,並且能更聚焦業務邏輯,更方便我們看程式碼。第二層面的意思,當某個元件的業務邏輯足夠複雜,setup中的程式碼足夠大的情況下,我們可以在setup內部,進一步提取相關的一塊業務,使程式碼邏輯更加清晰,做到了進一步的聚合作用。
如下面程式碼所示,將業務程式碼塊A抽出來,則程式碼塊A中return出來的資料就可以在元件中使用:
// 元件
import functionA from 'A'
export default defineComponent({
name: 'componentName',
setup() {
...functionA()
}
-
})
-
// 程式碼塊A
export default () => {
return {
a: 1
}
}
3 響應式API
在Vue3中響應式API,主要體現在ref和reactive兩個函式。對於響應式API,想說兩個問題,第一個是為什麼要增加響應式API,第二個是響應式API函式ref和reactive的異同點。
3.1 為什麼增加響應式API
在Vue2中所有資料都寫在data的option中,data中的資料都是響應式的,這樣產生的一個問題是,有些常量資料本身不需要監聽,從而造成了資源的浪費。所以在Vue3中增加了響應式API,只需要對需要動態更新dom的資料進行響應式,不需要動態更新dom的資料不進行響應式處理,從很大程度上節省了資源。這裡我覺得需要注意的是,寫程式碼的時候一定要仔細思考一下,哪些資料需要進行響應式繫結,哪些資料不需要進行響應式繫結,而不是一股腦的全給繫結上,這樣即使程式碼邏輯不能很清晰易懂,並且也會影響執行效率(寫慣了Vue2的同學需要注意)。
3.2 ref和reactive的異同點
在瞭解了為什麼要增加響應式API後,我們發現Vue3提供了兩個響應式API函式,ref和reactive。為什麼會提供兩個API呢? 一個不就可以了嗎?那麼這兩個API之間的區別是什麼呢?
在使用層面,ref繫結的資料,需要使用[data].value進行資料更改。而reactive繫結的資料需要使用[data].[prpoerty]的方式進行資料更改。在使用場景方面,一般的,單個的普通資料,我們使用ref來定義響應式。而複雜資料,如:表單資料物件、某一模組的一組資料等,使用reactive來定義響應式。
那麼,物件是不是必須用reactive來定義呢? 其實不是的,都可以。官方說法是:可以根據自身習慣使用不同的API。其實,我覺得,他們是有各自的使用場景的,ref更強調的是資料Value的改變,reactive更強調的是資料中某一屬性的改變。
4 treeShaking思想
當 Javascript 專案達到一定體積時,將程式碼分成模組會更易於管理。但是,當這樣做時,我們最終可能會匯入實際上未使用的程式碼。Tree Shaking 是一種通過消除最終檔案中未使用的程式碼來優化體積的方法。
Vue3使用了tree shaking的方法,將元件以及其所有的生命週期函式等方法進行分開,如果在元件中使用的程式碼將不會出現在最終的打包檔案中,如此,會減少大大Vue3專案的打包體積。由此造成的一個結果就是,使用方法的不同。
4.1 生命週期函式的使用方法
import { defineComponent, ref, onMounted } from 'vue';
export default defineComponent({
name: 'Gift',
setup() {
const counter = ref(0);
onMounted(() => {
// 處理業務,一般進行資料請求
})
return {
counter
}
}
})
4.2 Vuex的使用方法
import { useStore } from "vuex";
import { defineComponent, ref, computed } from 'vue';
export default defineComponent({
name: 'Gift',
setup() {
const counter = ref(0);
const store = useStore();
const storeData = computed(() => store); // 配合computed,獲取store的值。
return {
counter,
storeData
}
}
})
4.3 Router的使用方法
import { useStore } from "vuex";
import { useRouter } from "vue-router";
import { defineComponent, ref, computed } from 'vue';
export default defineComponent({
name: 'Gift',
setup() {
const counter = ref(0);
const router = useRouter();
const onClick = () => {
router.push({ name: "AddGift" });
}
return {
counter,
onClick
}
}
})
5 關於Typescript的使用
這一部分是關於Ts的內容,不過它與Vue3的開發息息相關。Vue3整體是使用Ts寫的,因此,開發Vue3的專案需要使用Ts,所以,我們還是要了解TS的。
關於Ts的使用這裡就不在細說了,在這裡想說的的是,在實際業務場景中是如何組織Ts程式碼的。通過對TS的大量使用,我的一個體會是:Ts的核心思維是先關注資料結構,在根據資料結構進行頁面開發。而以前的前端開發模式是,先寫頁面,然後再關注資料。
比如說,我們要開發一個頁面,我們可能需要先定義一些interface。開發頁面的時候我們要關注:頁面資料的interface、介面返回資料的型別、請求引數的型別等等。
下面是開發一個列表頁面的例子:
// 這是列表中每一項的資料型別
interface IDataItem {
id: string | number;
name: string;
desc: string;
[key: string]: any;
-
}
-
// 介面返回值型別, 一般來說,我們不確定介面返回的資料的型別,因此使用泛型
interface IRes<T> {
code: number;
msg: string;
data: T
-
}
-
// 口返回資料型別定義
interface IDataInfo {
list: Array<IDataItem>;
pageNum: number;
pageSize: number;
total: number;
-
}
-
// 請求
export const getDatalist = (
params: Record<string, any>
): Promise<IRes<IDataInfo>> => {
return Http.get("/api/data/list", params);
};
如上面程式碼,當我們的interface定義完成後,我們的頁面資料基本都已清楚,直接寫頁面就會清晰很多,且出錯概率會大大降低。
- 應用健康度隱患刨析解決系列之資料庫時區設定
- 對於Vue3和Ts的心得和思考
- 一文詳解擴散模型:DDPM
- zookeeper的Leader選舉原始碼解析
- 一文帶你搞懂如何優化慢SQL
- 京東金融Android瘦身探索與實踐
- 微前端框架single-spa子應用載入解析
- cookie時效無限延長方案
- 聊聊前端效能指標那些事兒
- Spring竟然可以建立“重複”名稱的bean?—一次專案中存在多個bean名稱重複問題的排查
- 京東金融Android瘦身探索與實踐
- Spring原始碼核心剖析
- 深入淺出RPC服務 | 不同層的網路協議
- 安全測試之探索windows遊戲掃雷
- 關於資料庫分庫分表的一點想法
- 對於Vue3和Ts的心得和思考
- Bitmap、RoaringBitmap原理分析
- 京東小程式CI工具實踐
- 測試用例設計指南
- 當你對 redis 說你中意的女孩是 Mia