1. 程式人生 > 其它 >vue3 + Typescript學習筆記 二

vue3 + Typescript學習筆記 二

技術標籤:vuevue.js

一、用 reactive()函式優化程式

  1. 上節課的程式碼可以說沒什麼章法可言,所有的變數和方法都混淆在一起,我最不能忍受的是在setup中要改變和讀取一個值的時候,還要加上value。這種程式碼一定是可以優化的,需要引入一個新的 APIreactive。它也是一個函式(方法),只不過裡邊接受的引數是一個 Object(物件)。
    然後無論是變數和方法,都可以作為 Object 中的一個屬性,而且在改變selectGirl值的時候也不用再加討厭的value屬性了。再return返回的時候也不用一個個返回了,只需要返回一個data,就可以了。

    <script
    lang="ts">
    import { ref, reactive } from "vue"; export default { name: "App", setup() { const data = reactive({ girls: ["大腳", "劉英", "曉紅"], selectGirl: "", selectGirlFun: (index: number) => { data.
    selectGirl = data.girls[index]; }, }); return { data, }; }, };
    </script>
  2. 修改完成<script>部分的程式碼後,還需要修改template部分的程式碼,因為我們這時候返回的只有data,所以模板部分的字面量前要加入data。

    <template>
      <img alt="Vue logo" src="./assets/logo.png" />
      <div>
        <
    h2
    >
    歡迎光臨紅浪漫洗浴中心</h2> <div>請選擇一位美女為你服務</div> </div> <div> <button v-for="(item, index) in data.girls" v-bind:key="index" @click="data.selectGirlFun(index)" > {{ index }} : {{ item }} </button> </div> <div>你選擇了【{{ data.selectGirl }}】為你服務</div> </template>
  3. 這個修改完成後,可以在Terminal終端裡開啟yarn serve,檢視一下效果了,如果沒有錯誤,應該和原來的效果一樣。效果雖然一樣,但是這時候程式碼,要比上節課優雅了很多。著一些的功勞要歸屬於reactive函式。

    給 data 增加型別註解

  4. 這時的程式碼雖然可以完美的執行,但是細心的小夥伴可以發現data這個變數,我們並沒有作型別註解,而是採用了TypeScript的型別推斷。
    這樣的程式碼,在我們公司是不允許出現的,必須要增加型別註解。所以我們先定義一個介面,用介面(interface)來作型別註解。

    interface DataProps {
      girls: string[];
      selectGirl: string;
      selectGirlFun: (index: number) => void;
    }
    

    編寫完成後,你在顯示的為 data 變數作一個型別註解.

    cosnt data: DataProps = ...
    

用 toRefs()繼續優化

  1. 現在template中,每次輸出變數前面都要加一個data,這是可以優化的。有的小夥伴說了,我用…擴充套件運算子就可以解決這個問題了。
    在這裡我就可以告訴你不行,因為結構後就變成了普通變數,不再具有響應式的能力。所以要解決這個問題,需要使用 Vue3 的一個新函式toRefs()。使用前需要先進行引入。

    import { reactive, toRefs } from "vue";
    

    引入後就可以對data進行包裝,把 data 變成refData,這樣就可以使用擴充套件運算子的方式了。具體程式碼如下:

     export default {
      name: "App",
      setup() {
        // const girls = ref(["大腳", "劉英", "曉紅"]);
        // const selectGirl = ref("");
        // const selectGirlFun = (index: number) => {
        //   selectGirl.value = girls.value[index];
        // };
        const data: DataProps = reactive({
          girls: ["大腳", "劉英", "曉紅"],
          selectGirl: "",
          selectGirlFun: (index: number) => {
            data.selectGirl = data.girls[index];
          },
        });
        const refData = toRefs(data);
    
        return {
          ...refData,
        };
      },
    };
    

    這樣寫之後,你的template就應該去掉 data,而是直接使用變數名和方法,就可以了。

    <template>
      <img alt="Vue logo" src="./assets/logo.png" />
      <div>
        <h2>歡迎光臨紅浪漫洗浴中心</h2>
        <div>請選擇一位美女為你服務</div>
      </div>
      <div>
        <button
          v-for="(item, index) in girls"
          v-bind:key="index"
          @click="selectGirlFun(index)"
        >
          {{ index }} : {{ item }}
        </button>
      </div>
      <div>你選擇了【{{ selectGirl }}】為你服務</div>
    </template>
    

如何選擇 Ref()和 reactive()

  1. 網路上對這兩個方法的爭論還是不少的,但到目前為止,還沒有什麼實質性的理論到底是用Ref()好,還是reactive()好,也就是兩種方法都可以。他們的作用都是生成響應式物件,目前來看只是編寫上有所不同。
    我個人更傾向於使用reactive(),因為它讓程式看起來更規範。如果你學到這裡還猶豫不定,也沒關係,隨著你進一步的深入學習,一定會有你自己的最佳選擇。

二、Vue3.x 的生命週期和鉤子函式

  1. Vue3 版本的生命週期和 Vue2 比有了些變化,所以我先站在一個初學者的角度(沒有學過 Vue2 版本的新手),從新講一下 Vue3.x 的生命週期,等你完全理解之後,我們再來和 Vue2.x 的生命週期作一個對比。

  2. 什麼是生命週期

  3. Vue 是元件化程式設計,從一個元件誕生到消亡,會經歷很多過程,這些過程就叫做生命週期。

  4. 來個比喻,生命週期和人從出生到入土是一樣的。有少年時期、有青年時期、有中年時期、有老年時期。每個時期都應該有不同的任務,可以作不同的事。
    當你理解了什麼是生命週期,你還了解一個概念“鉤子函式”。

  5. 鉤子函式: 伴隨著生命週期,給使用者使用的函式,操控生命週期,主要是操控鉤子函式。
    Vue3 的生命週期比較多,我們需要一個個給大家講。

    setup() :開始建立元件之前,在beforeCreate和created之前執行。建立的是data和method
    onBeforeMount() : 元件掛載到節點上之前執行的函式。
    onMounted() : 元件掛載完成後執行的函式。
    onBeforeUpdate(): 元件更新之前執行的函式。
    onUpdated(): 元件更新完成之後執行的函式。
    onBeforeUnmount(): 元件解除安裝之前執行的函式。
    onUnmounted(): 元件解除安裝完成後執行的函式
    onActivated(): 被包含在<keep-alive>中的元件,會多出兩個生命週期鉤子函式。被啟用時執行。
    onDeactivated(): 比如從 A 元件,切換到 B 元件,A 元件消失時執行。
    onErrorCaptured(): 當捕獲一個來自子孫元件的異常時啟用鉤子函式(以後用到再講,不好展現)。
    
  6. 注:使用元件會將資料保留在記憶體中,比如我們不想每次看到一個頁面都重新載入資料,就可以使用元件解決。

三、鉤子函式的使用

  1. Vue3.x 生命週期在呼叫前需要先進行引入,我們先暫時演示前五個生命週期。

    import {
      reactive,
      toRefs,
      onMounted,
      onBeforeMount,
      onBeforeUpdate,
      onUpdated,
    } from "vue";
    
  2. 先來說setup(),setup 這個函式是在beforeCreate和created之前執行的,所以你可以用它來代替這兩個鉤子函式。
    為了看出鉤子函式執行的時機,我在setup()函式裡,編寫了下面的程式碼:

    <script lang="ts">
    
    //....
    const app = {
      name: "App",
      setup() {
        console.log("1-開始建立元件-----setup()");
        const data: DataProps = reactive({
          girls: ["大腳", "劉英", "曉紅"],
          selectGirl: "",
          selectGirlFun: (index: number) => {
            data.selectGirl = data.girls[index];
          },
        });
        onBeforeMount(() => {
          console.log("2-元件掛載到頁面之前執行-----onBeforeMount()");
        });
    
        onMounted(() => {
          console.log("3-元件掛載到頁面之後執行-----onMounted()");
        });
        onBeforeUpdate(() => {
          console.log("4-元件更新之前-----onBeforeUpdate()");
        });
    
        onUpdated(() => {
          console.log("5-元件更新之後-----onUpdated()");
        });
    
        const refData = toRefs(data);
    
        return {
          ...refData,
        };
      },
    };
    export default app;
    </script>
    
  3. 寫完後可以到瀏覽器看一下效果,效果和你想象的應該是一樣的。

    1 - 開始建立元件---- - setup();
    2 - 元件掛載到頁面之前執行---- - onBeforeMount();
    3 - 元件掛載到頁面之後執行---- - onMounted();
    4 - 元件更新之前---- - onBeforeUpdate();
    5 - 元件更新之後---- - onUpdated();
    
  4. 你這時候一定會有個疑問,那Vue2.X版本的生命週期函式還可以使用嗎?答案是肯定的。
    你可以在setup()函式之後編寫Vue2的生命週期函式,程式碼如下:

    beforeCreate() {
      console.log("1-元件建立之前-----beforeCreate()");
    },
    beforeMount() {
      console.log("2-元件掛載到頁面之前執行-----BeforeMount()");
    },
    mounted() {
      console.log("3-元件掛載到頁面之後執行-----Mounted()");
    },
    beforeUpdate() {
      console.log("4-元件更新之前-----BeforeUpdate()");
    },
    updated() {
      console.log("5-元件更新之後-----Updated()");
    },
    

    這時候可以看到,原來的生命週期也是完全可以使用。