基于 Vue3 和 TypeScript 項(xiàng)目大量實(shí)踐后的思考

概述

Vue3出來已經(jīng)有一段時(shí)間了,在團(tuán)隊(duì)中驱负,也進(jìn)行了大量的業(yè)務(wù)實(shí)踐,也有了一些自己的思考患雇。

總的來說跃脊,Vue3無論是在底層的原理上,還是在業(yè)務(wù)的實(shí)際開發(fā)中苛吱,都有了長足的進(jìn)步匾乓。

使用 proxy 代替之前的 Object.defineProperty 的API,性能更加優(yōu)異又谋,也解決了之前vue在處理對象拼缝、數(shù)組上的缺陷;在diff算法上彰亥,使用了靜態(tài)標(biāo)記的方式咧七,大大提升了Vue的執(zhí)行效率。

在使用的層面任斋,我們從options Api继阻,變成了composition Api,慢慢的在實(shí)際的業(yè)務(wù)中废酷,我們拋棄了原本的data瘟檩、methods、computed那種隔離式的寫法澈蟆。compositon Api墨辛,它更加聚焦,它講究的是相關(guān)業(yè)務(wù)的聚合性趴俘。

同時(shí)睹簇,在composition Api中,為了防止過于重的業(yè)務(wù)邏輯寥闪,它提供了一種關(guān)注點(diǎn)分離的方式太惠,大大的提升了我們代碼的可讀性。

完全良好的支持了TypeScript疲憋,類型校驗(yàn)也成為了以后Vue3進(jìn)行大型項(xiàng)目開發(fā)的質(zhì)量保障凿渊,同時(shí)這也是面向了趨勢 -- 前端的未來就是TypeScript!

1缚柳、compositon Api

compositon Api的本質(zhì)埃脏,體現(xiàn)在代碼里面,也就是一個(gè)setup函數(shù)喂击,在這個(gè)setup函數(shù)中剂癌,返回的數(shù)據(jù),會用到該組件的模板中翰绊。return的這個(gè)對象佩谷,一定程度上,代表了之前vue2中的data屬性监嗜。

import { defineComponent, ref } from 'vue';
export default defineComponent({ 
    name: 'Gift',   
    setup() {     
        const counter = ref(0);    
        return {        
            counter     
        }  
    }
})

這時(shí)候谐檀,對于大多數(shù)初學(xué)者來說,可能存在的疑惑就是裁奇,那么我能不能定義options Api的寫法桐猬,比如data、computed刽肠、watch溃肪、methods等等免胃。

這里我需要明確的是,Vue3是完全兼容Vue2的這種options Api的寫法惫撰,但是從理念上來說羔沙,更加推薦setup的方式,來寫我們的組件厨钻。

原因如下:Vue3的存在扼雏,本身是為了解決Vue2的問題的,Vue2的問題就是在于夯膀,聚合性不足诗充,會導(dǎo)致代碼越來越臃腫!setup的方式诱建,能夠讓data蝴蜓、方法邏輯、依賴關(guān)系等聚合在一塊涂佃,更方便維護(hù)励翼。

也就是說,以后我們盡量不要寫單獨(dú)的data辜荠、computed汽抚、watch、methods等等伯病,不是Vue3不支持造烁,而是和Vue3的理念違背。

components屬性午笛,也就是一個(gè)組件的子組件惭蟋,這個(gè)配置在Vue2和3的差異不大,Vue2怎么用药磺,Vue3依然那么用告组。

1、ref 和 reactive的區(qū)別癌佩?

在功能方面木缝,ref 和 reactive,都是可以實(shí)現(xiàn)響應(yīng)式數(shù)據(jù)围辙!

在語法層面我碟,兩個(gè)有差異。ref定義的響應(yīng)式數(shù)據(jù)需要用[data].value的方式進(jìn)行更改數(shù)據(jù)姚建;reactive定義的數(shù)據(jù)需要[data].[prpoerty]的方式更改數(shù)據(jù)矫俺。

const actTitle: Ref<string> = ref('活動名稱');

const actData = reactive({  
    list: [], 
    total: 0, 
    curentPage: 1,  
    pageSize: 10
});

actTitle.value = '活動名稱2';

actData.total = 100; 

但是在應(yīng)用的層面,還是有差異的,通常來說:單個(gè)的普通類型的數(shù)據(jù)厘托,我們使用ref來定義響應(yīng)式友雳。表單場景中,描述一個(gè)表單的key:value這種對象的場景催烘,使用reactive沥阱;在一些場景下,某一個(gè)模塊的一組數(shù)據(jù)伊群,通常也使用reactive的方式,定義數(shù)據(jù)策精。

那么舰始,對象是不是非要使用reactive來定義呢?其實(shí)不是的咽袜,都可以丸卷,根據(jù)自己的業(yè)務(wù)場景,具體問題具體分析询刹!ref他強(qiáng)調(diào)的是一個(gè)數(shù)據(jù)的value的更改谜嫉,reactive強(qiáng)調(diào)的是定義的對象的某一個(gè)屬性的更改。

2凹联、周期函數(shù)

周期函數(shù)沐兰,在Vue3中,是被單獨(dú)使用的蔽挠,使用方式如下:

import { defineComponent, ref, onMounted } from 'vue';
export default defineComponent({  
    name: 'Gift',  
    setup() {    
        const counter = ref(0);    
        onMounted(() => {     
            // 處理業(yè)務(wù)住闯,一般進(jìn)行數(shù)據(jù)請求      
        })  
        return {       
            counter     
        }  
    }
})

3、store使用

在Vue2中澳淑,其實(shí)可以直接通過this.$store進(jìn)行獲取比原,但是在Vue3中,其實(shí)沒有this這個(gè)概念杠巡,使用方式如下:

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氢拥、router的使用

在Vue2中蚌铜,是通過this.$router的方式,進(jìn)行路由的函數(shù)式編程兄一,但是Vue3中厘线,是這么使用的:

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     
        }  
    }
}) 

2、關(guān)注點(diǎn)分離

關(guān)注點(diǎn)分離出革,應(yīng)該分兩層意思:第一層意思就是造壮,Vue3的setup,本身就把相關(guān)的數(shù)據(jù),處理邏輯放到一起耳璧,這就是一種關(guān)注點(diǎn)的聚合成箫,更方便我們看業(yè)務(wù)代碼。

第二層意思旨枯,就是當(dāng)setup變的更大的時(shí)候蹬昌,我們可以在setup內(nèi)部,提取相關(guān)的一塊業(yè)務(wù)攀隔,做到第二層的關(guān)注點(diǎn)分離皂贩。

import { useStore } from "vuex";
import { useRouter } from "vue-router";
import { defineComponent, ref, computed } from 'vue';
import useMerchantList from './merchant.js';
export default defineComponent({  
    name: 'Gift',  
    setup() {   
        const counter = ref(0);     
        const router = useRouter();    
        const onClick = () => {       
            router.push({ name: "AddGift" });      
        }   
        // 在該示例中,我們把獲取商家列表的相關(guān)業(yè)務(wù)分離出去昆汹。也就是下面的merchant.ts    
        const {merchantList} = useMerchantList();    
        return {        
            counter,     
            onClick,      
            merchantList    
        } 
    }
})

merchant.ts

import { getMerchantlist } from "@/api/rights/gift";
import { ref, onMounted } from "vue";

export default function useMerchantList(): Record<string, any> { 
  const merchantList = ref([]); 
  const fetchMerchantList = async () => {  
    let res = await getMerchantlist({}); 
    merchantList.value = res?.data?.child; 
  }; 

  onMounted(fetchMerchantList); 

  return {  
    merchantList 
  };
}

3明刷、TypeScript支持

這一部分內(nèi)容,準(zhǔn)確的來說满粗,是TS的內(nèi)容辈末,不過它與Vue3項(xiàng)目開發(fā),息息相關(guān)映皆,所以真的想用Vue3挤聘,我們還是得了解TS的使用。

不過這一部分捅彻,我不會介紹TS的基礎(chǔ)語法组去,主要是在業(yè)務(wù)場景中,如何組織TS沟饥。

使用TS進(jìn)行業(yè)務(wù)開發(fā)添怔,一個(gè)核心的思維是,先關(guān)注數(shù)據(jù)結(jié)構(gòu)贤旷,再根據(jù)數(shù)據(jù)結(jié)構(gòu)進(jìn)行頁面開發(fā)广料。以前的前端開發(fā)模式是,先寫頁面幼驶,后關(guān)注數(shù)據(jù)艾杏。

比如要寫一個(gè)禮品列表的頁面,我們可能要定義這么一些interface盅藻」荷#總而言之,我們需要關(guān)注的是:頁面數(shù)據(jù)的interface氏淑、接口返回的數(shù)據(jù)類型勃蜘、接口的入?yún)㈩愋偷鹊取?/p>

// 禮品創(chuàng)建、編輯假残、列表中的每一項(xiàng)缭贡,都會是這個(gè)數(shù)據(jù)類型炉擅。
interface IGiftItem { 
  id: string | number; 
  name: string; 
  desc: string; 
  [key: string]: any;
}

// 全局相應(yīng)的類型定義
// 而且一般來說,我們不確認(rèn)阳惹,接口返回的類型到底是什么(可能是null谍失、可能是對象、也可能是數(shù)組)莹汤,所以使用范型來定義
interface IRes<T> {  
    code: number;  
    msg: string;  
    data: T
}

// 接口返回?cái)?shù)據(jù)類型定義
interface IGiftInfo {  
    list: Array<IGiftItem>;  
    pageNum: number;  
    pageSize: number;  
    total: number;
} 

在一個(gè)常見的接口請求中快鱼,我們一般使用TS這么定義一個(gè)數(shù)據(jù)請求,數(shù)據(jù)請求的req類型纲岭,數(shù)據(jù)請求的res類型抹竹。

export const getGiftlist = ( 
  params: Record<string, any>
): Promise<IRes<IGiftInfo>> => {  
  return Http.get("/apis/gift/list", params);
};
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市止潮,隨后出現(xiàn)的幾起案子柒莉,更是在濱河造成了極大的恐慌,老刑警劉巖沽翔,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異窿凤,居然都是意外死亡仅偎,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進(jìn)店門雳殊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來橘沥,“玉大人,你說我怎么就攤上這事夯秃∽兀” “怎么了?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵仓洼,是天一觀的道長介陶。 經(jīng)常有香客問我,道長色建,這世上最難降的妖魔是什么哺呜? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮箕戳,結(jié)果婚禮上某残,老公的妹妹穿的比我還像新娘。我一直安慰自己陵吸,他們只是感情好玻墅,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著壮虫,像睡著了一般澳厢。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天赏酥,我揣著相機(jī)與錄音喳整,去河邊找鬼。 笑死裸扶,一個(gè)胖子當(dāng)著我的面吹牛框都,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播呵晨,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼魏保,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了摸屠?” 一聲冷哼從身側(cè)響起谓罗,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎季二,沒想到半個(gè)月后檩咱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡胯舷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年刻蚯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片桑嘶。...
    茶點(diǎn)故事閱讀 39,991評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡炊汹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出逃顶,到底是詐尸還是另有隱情讨便,我是刑警寧澤,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布以政,位于F島的核電站霸褒,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏妙蔗。R本人自食惡果不足惜傲霸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望眉反。 院中可真熱鬧昙啄,春花似錦、人聲如沸寸五。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽梳杏。三九已至韧拒,卻和暖如春淹接,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背叛溢。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工塑悼, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人楷掉。 一個(gè)月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓厢蒜,卻偏偏與公主長得像,于是被迫代替她去往敵國和親烹植。 傳聞我的和親對象是個(gè)殘疾皇子斑鸦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內(nèi)容