<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          基于 Vue3 和 TypeScript 項目大量實踐后的思考

          共 9148字,需瀏覽 19分鐘

           ·

          2021-11-19 13:34

          大廠技術(shù)  高級前端  Node進階

          點擊上方 程序員成長指北,關(guān)注公眾號

          回復(fù)1,加入高級Node交流群


          概述

          Vue3出來已經(jīng)有一段時間了,在團隊中,也進行了大量的業(yè)務(wù)實踐,也有了一些自己的思考。

          總的來說,Vue3無論是在底層的原理上,還是在業(yè)務(wù)的實際開發(fā)中,都有了長足的進步。

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

          在使用的層面,我們從options Api,變成了composition Api,慢慢的在實際的業(yè)務(wù)中,我們拋棄了原本的data、methods、computed那種隔離式的寫法。compositon Api,它更加聚焦,它講究的是相關(guān)業(yè)務(wù)的聚合性。同時,在composition Api中,為了防止過于重的業(yè)務(wù)邏輯,它提供了一種關(guān)注點分離的方式,大大的提升了我們代碼的可讀性。

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

          1、compositon Api

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

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

          這時候,對于大多數(shù)初學(xué)者來說,可能存在的疑惑就是,那么我能不能定義options Api的寫法,比如data、computed、watch、methods等等。

          這里我需要明確的是,Vue3是完全兼容Vue2的這種options Api的寫法,但是從理念上來說,更加推薦setup的方式,來寫我們的組件。原因如下:Vue3的存在,本身是為了解決Vue2的問題的,Vue2的問題就是在于,聚合性不足,會導(dǎo)致代碼越來越臃腫!setup的方式,能夠讓data、方法邏輯、依賴關(guān)系等聚合在一塊,更方便維護。

          也就是說,以后我們盡量不要寫單獨的data、computed、watch、methods等等,不是Vue3不支持,而是和Vue3的理念違背。

          components屬性,也就是一個組件的子組件,這個配置在Vue2和3的差異不大,Vue2怎么用,Vue3依然那么用。

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

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

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

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

          const actData = reactive({
              list: [],
              total0,
              curentPage1,
              pageSize10
          });

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

          actData.total = 100;

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

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

          2、周期函數(shù)

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

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


          3、store使用

          在Vue2中,其實可以直接通過this.$store進行獲取,但是在Vue3中,其實沒有this這個概念,使用方式如下:

          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的方式,進行路由的函數(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)注點分離

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

          第二層意思,就是當(dāng)setup變的更大的時候,我們可以在setup內(nèi)部,提取相關(guān)的一塊業(yè)務(wù),做到第二層的關(guā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<stringany{
            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項目開發(fā),息息相關(guān),所以真的想用Vue3,我們還是得了解TS的使用。

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

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

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

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

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

          interface IGiftInfo {
              list: Array<IGiftItem>;
              pageNum: number;
              pageSize: number;
              total: number;
          }

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

          export const getGiftlist = (
            params: Record<stringany>
          ): Promise<IRes<IGiftInfo>> => {
            return Http.get("/apis/gift/list", params);
          };


          關(guān)于本文:

          來源:mapbar_front

          https://juejin.cn/post/7008063765585330207

          Node 社群


          我組建了一個氛圍特別好的 Node.js 社群,里面有很多 Node.js小伙伴,如果你對Node.js學(xué)習(xí)感興趣的話(后續(xù)有計劃也可以),我們可以一起進行Node.js相關(guān)的交流、學(xué)習(xí)、共建。下方加 考拉 好友回復(fù)「Node」即可。


             “分享、點贊在看” 支持一波??

          瀏覽 52
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  一级黄色电影视频 | 欧美一级成人 | 久久精品国产亚洲AV苍井空 | 伊人在线观看视频网站 | 国产无码乱伦视频 |