Vue.js 學習筆記之七:使用現有元件

凌傑發表於2021-03-15

在之前的實驗中,我們所演示的基本都是如何構建自定義元件的方法,但在具體開發實踐中,並非專案中所有的元件都是需要程式設計師們自己動手來建立的。畢竟在程式設計領域,“不要重複發明輪子”也是一項理應受到所有程式設計師遵守的基本原則。換而言之,在親自動手建立一個元件之前,程式設計師們理應先確認一下 Vue.js 框架的內建元件庫,以及當前流行的第三方元件庫中是否已經提供了類似功能的元件。如果有的話,就直接拿來使用即可,不必再去自定義一個功能重複的元件了。遵守這一基本原則不僅可以避免重複勞動,提高程式設計師們的專案開發效率,而且由於這些元件庫提供的元件通常都經歷過更嚴格、更系統性的測試和優化,所以直接使用它們來完成相關任務也有助於改善程式本身的效能和安全性。

使用內建元件

根據 Vue.js 框架的官方文件,該框架主要為使用者提供了以下五個內建元件,讓我們先來簡單介紹這些元件的功能:

  • component元件:該元件主要用於在使用者介面中進行介面元素(包括自定義標籤)的動態切換。
  • transition元件:該元件主要用於定義在使用者介面中切換介面元素(包括自定義標籤)時的動畫效果。
  • transition-group元件:該元件主要用於定義在使用者介面中分組切換多個介面元素(包括自定義標籤)時的動畫效果。
  • keep-alive元件:該元件主要用於在元件切換的過程中快取不活動的元件物件,以便該元件被切換回來時能維持之前的狀態。
  • slot元件:該元件主要用於在自定義元件模板預留其他元件標籤或 HTML 標準標籤可以插入的插槽位置。

細心的讀者可能已經發現了,上述元件除了slot元件是用於在自定義元件時預留插槽之外(我們在之前的實驗中已經演示過了該元件的使用方法),其他四個元件都與使用者介面中介面元素的切換有關。這讓人想到通過一個讓使用者在登入介面和註冊介面之間來回切換的實驗來演示這些內建元件的使用方法。下面先從component元件開始,讓我們執行以下步驟來開始構建這個筆記系列的第六個實驗:

  1. 首先在code/otherTest目錄中再建立一個名為component_users的目錄,並在該目錄下建立publicsrc這兩個子目錄。

  2. 由於component_users實驗所需要的依賴項以及目錄結構都與component_wp實驗相同,為了免除不必要的工作量,節省花費在該實驗專案配置工作上的時間,我們可以直接將component_wp目錄下的package.jsonwebpack.config.js這兩個分別與依賴項與專案打包相關的配置檔案複製到component_users目錄下(並根據需要稍作修改),然後在component_users目錄下執行npm install命令來安裝已經配置在package.json檔案中的專案依賴項。

  3. src目錄下建立一個名為userLogin.vue檔案,並在其中建立用於定義使用者登入介面的元件。具體程式碼如下:

     <template>
         <div id="tab-login">
             <table>
                 <tr>
                     <td>使用者名稱:</td>
                     <td><input type="text" v-model="userName"></td>
                 </tr>
                 <tr>
                     <td>密  碼:</td>
                     <td><input type="password" v-model="password"></td>
                 </tr>
                 <tr>
                     <td><input type="button" value="登入" @click="login"></td>
                     <td><input type="button" value="重置" @click="reset"></td>
                 </tr>
             </table>
         </div>
     </template>
     <script>
         export default {
             name: "tab-login",
             props : ['value'],
             data: function() {
                 return {
                     userName: '',
                     password: ''
                 };
             },
             methods: {
                 login: function() {
                     if(this.userName !== '' && this.password !== '') {
                         if(this.userName === 'owlman' && this.password === '0000') {
                             this.$emit('input', true);
                         } else {
                             window.alert('使用者名稱或密碼錯誤!');
                             
                         }
                     } else {
                         window.alert('使用者名稱與密碼都不能為空!');
    
                     }
                 },
                 reset: function() {
                     this.userName = '';
                     this.password = '';
                 }
             }
     };
     </script>
    
  4. src目錄下建立一個名為userSignUp.vue檔案,並在其中建立用於定義使用者註冊介面的元件。具體程式碼如下:

     <template>
         <div id="tab-sign">
             <table>
                 <tr>
                     <td>請輸入使用者名稱:</td>
                     <td><input type="text" v-model="userName"></td>
                 </tr>
                 <tr>
                     <td>請設定密碼:</td>
                     <td><input type="password" v-model="password"></td>
                 </tr>
                 <tr>
                     <td>請重複密碼:</td>
                     <td><input type="password" v-model="rePassword"></td>
                 </tr>
                 <tr>
                     <td><input type="button" value="註冊" @click="signUp"></td>
                     <td><input type="button" value="重置" @click="reset"></td>
                 </tr>
             </table>
         </div>
     </template>
     <script>
         export default {
             name: "tab-sign",
             data() {
                 return {
                     userName: '',
                     password: '',
                     rePassword: ''
                 };
             },
             methods: {
                 signUp: function() {
                     if(this.userName !== '' &&
                     this.password !== '' &&
                     this.rePassword !== '') {
                         if(this.password === this.rePassword) {
                             window.alert('使用者註冊');
                         } else {
                             window.alert('你兩次輸入的密碼不一致!');
                         }
                     } else {
                         window.alert('請正確填寫註冊資訊!');
                     }
    
                 },
                 reset: function() {
                     this.userName = '';
                     this.password = '';
                     this.rePassword = '';
                 }
             }
         };
     </script>
    
  5. src目錄下建立main.js檔案,並在實現 Vue 物件時將上面兩個新建的元件註冊成區域性元件,具體程式碼如下:

     import Vue from 'vue';
     import userLogin from './userLogin.vue';
     import userSignUp from './userSignUp.vue';
    
     new Vue({
         el: '#app',
         data: {
             componentId: 'login',
             isLogin: false
         },
         components: {
             login: userLogin,
             signup : userSignUp
         }
     })
    
  6. src目錄下建立index.htm檔案,並在設計應用程式的使用者介面時使用<component>標籤指定首先要載入的元件,並用<input>標籤在該介面中設定兩個用於切換元件的按鈕元素,具體程式碼如下:

     <!DOCTYPE html>
     <html lang="zh-cn">
         <head>
             <meta charset="UTF-8">
             <style>
                 body {
                     background: black;
                     color: floralwhite;
                 }
                 .box {
                 width: 400px;
                 height: 300px;
                 border-radius: 14px;
                 padding: 14px;
                 color: black;
                 background: floralwhite;
             }
             </style>
             <title>Vue 元件實驗(6):使用動態元件</title>
         </head>
         <body>
             <div id="app" class="box">
                 <h1>使用者登入</h1>
                 <div v-show="!isLogin">
                     <input type="button" value="註冊新使用者"
                         @click="componentId='signup'">
                     <input type="button" value="使用者登入" 
                         @click="componentId='login'">
                     <component :is="componentId" v-model="isLogin"></component>
                 </div>
                 <div v-show="isLogin">登入成功</div>
             </div>
         </body>
     </html>
    
  7. 用瀏覽器訪問public目錄下的index.html檔案,就可以看到最後的結果了,如下圖所示:

    使用者的登入與註冊

在上述程式碼中,讀者可以看到我們在使用component元件時主要設定了兩個屬性。首先是is屬性,這是使用component元件必須要設定的屬性。該屬性應該是一個字串型別的值,主要用於在一組要被切換的元件中指定當前被啟用的元件。在這裡,我們先用v-bind指令將其繫結到了 Vue 物件中一個名為componentIddata成員上,然後再通過兩個按鈕元素的單擊事件來改變該屬性的值,從而實現了在userLoinuserSignUp這兩個元件之間的切換。接下來是用v-model指令雙向繫結的 Vue 物件中另一個名為isLogindata成員,這不是使用component元件必須要設定的數學,我們繫結該資料是為了記錄使用者的登入狀態,並以此來決定應用程式是否需要在使用者介面中顯示與使用者登入與註冊功能相關的介面元素。

實驗進行到這一步,我們事實上已經在應用程式的使用者介面中初步實現了一個與使用者登入與註冊功能相關的模組,但這個模組還存在著一個小問題亟待解決,那就是元件在被切換時已經獲得的使用者輸入會被丟失。也就是說,如果我們在使用者註冊介面中輸入資訊的過程中不小心用滑鼠單擊了“使用者登入”按鈕元素,因此切換到了使用者登入介面,然後再切換回去時之前輸入的資訊就會全部丟失,這在使用者註冊時需要輸入輸入較多資訊的應用程式中可能會帶來較差的使用者體驗,在 Vue.js 框架中,我們可以使用keep-alive元件來解決這個問題,該元件的使用方法非常簡單,只需要將上面的component元件的標籤放到keep-alive元件的標籤內部即可,像這樣:

<keep-alive>
    <component :is="componentId" v-model="isLogin"></component>
</keep-alive>

除此之外,程式設計師們還可以通過在transition元件在介面元素切換過程中加入一些自己想要的過渡效果。下面是我們在使用transition元件可以設定的主要屬性:

  • name屬性:該屬性是一個字串型別的值,主要用於自動生成介面元素在切換過程中過渡樣式的 CSS 類名。例如當我們將name屬性的值設定為'usersModule'時,就等於自動建立了.usersModule-enter.usersModule-enter-active等一系列樣式的 CSS 類名。
  • appear屬性:該屬性是一個布林型別的值,主要用於指定是否要在使用者介面初始化時就使用過渡樣式。預設值為false
  • css屬性:該屬性是一個布林型別的值,主要用於指定是否要使用 CSS 樣式類來定義過渡效果。預設值為true
  • type屬性:該屬性是一個字串型別的值,主要用於指定過渡事件型別,偵聽過渡何時結束。有效值包括transitionanimation
  • mode屬性:該屬性是一個字串型別的值,主要用於控制介面元素退出/進入過渡的時間序列。有效值包括out-inin-out

通常情況下,我們只需依靠 CSS 樣式就可以實現一些簡單夠用的過渡效果了。但當transition元件的css屬性值為false或需要實現更復雜的過渡效果時,就需要通過定義一些由transition元件預設的事件鉤子函式來定義一些需要通過 JavaScript 程式碼來執行的操作,下面是我們在使用transition元件時可以定義的主要事件鉤子函式:

  • before-enter函式:該鉤子函式會在相關介面元素進入之前使用者介面時被呼叫。
  • before-leave函式:該鉤子函式會在相關介面元素退出之前使用者介面時被呼叫。
  • enter函式:該鉤子函式會在相關介面元素進入使用者介面時被呼叫。
  • leave函式:該鉤子函式會在相關介面元素退出使用者介面時被呼叫。
  • after-enter函式:該鉤子函式會在相關介面元素進入之後使用者介面時被呼叫。
  • after-leave函式:該鉤子函式會在相關介面元素退出之後使用者介面時被呼叫。

這裡需要說明的是,以上列出的只是一些常用的屬性和函式,並非是transition元件提供的所有屬性和事件鉤子函式,讀者如果閱讀關於該元件更全面的參考資料,還請自行去查閱 Vue.js 的官方文件[^3]。下面,我們來簡單示範一下transition元件的基本使用方式。在之前的第六個實驗中,如果想在userLoinuserSignUp這兩個元件的切換過程中加入一些過渡效果,可以將要切換的元件放到transition元件標籤內部,並根據需要設定該元件的屬性,例如像這樣:

<transition name='usersModule' mode='out-in'>                
    <keep-alive>
        <component :is="componentId" v-model="isLogin"></component>
    </keep-alive>
</transition>

在這裡,我們先將transition元件的mode屬性設定成了out-in,使得介面元素的切換順序變成了先退出再進入,然後在將其name屬性設定成了userModule。正如之前所說,name屬性的設定會自動建立一系列用於定義過渡效果 CSS 類名。下面,我們只需要根據專案的需要在index.htm檔案的<style>標籤或其外鏈的 CSS 檔案中定義一下其中的某個類,例如像這樣:

@keyframes usersAni {
    0% {
        transform: scale(0);
    }
    50% {
        transform: scale(1.5);
    }
    100% {
        transform: scale(1);
    }
}
.usersModule-leave-active {
    animation: usersAni .5s;
}

如你所見,我們在上述程式碼中定義了一個縮小放大效果的簡單過場動畫,然後在名為usersModule-leave-active的 CSS 類中使用了它。這樣一來,讀者就可以在userLoinuserSignUp這兩個元件的切換過程中看到類似放大鏡掃過的過渡效果了。當然,當前這個實驗中演示的只是最簡單的過渡效果設定。在後續具體的專案實踐中,我們將陸續演示如何使用transition元件和transition-group元件設定出更復雜、更具實用功能的過渡效果。

引入外部元件

由於 Vue.js 是一個開放性的前端框架,所以這些年在開源社群已經累積了不少既美觀又好用的第三方元件庫。在實際專案中,程式設計師們更多時候會選擇從外部引入第三方的元件來構建應用程式的使用者介面。下面,我們就以 Element 元件庫為例來介紹一下如何在一個基於 Vue.js 框架的前端專案中引入第三方元件庫。

  1. 先來建立第七個實驗專案所在的目錄,即在code/otherTest目錄中再建立一個名為hello_element的目錄,並在該目錄下建立publicsrc這兩個子目錄。

  2. 由於hello_element實驗所需要的依賴項以及目錄結構都與component_wp實驗相同,為了免除不必要的工作量,節省花費在該實驗專案配置工作上的時間,我們可以直接將component_wp目錄下的package.jsonwebpack.config.js這兩個分別與依賴項與專案打包相關的配置檔案複製到hello_element目錄下(並根據需要稍作修改),然後在hello_element目錄下執行npm install命令來安裝已經配置在package.json檔案中的專案依賴項。

  3. hello_element目錄下執行npm install --save element-ui命令將 Element 元件庫安裝到當前實驗專案中。

  4. src目錄下建立main.js檔案。在該檔案中,我們會先使用import語句分別匯入 Vue.js 框架與 Element 元件庫,接著再通過呼叫Vue.use()方法將 Element 元件庫載入到 Vue.js 框架中。然後就可以照常建立 Vue 物件了,具體程式碼如下:

     import Vue from 'vue';
     import ElementUI from 'element-ui';
    
     Vue.use(ElementUI);
    
     new Vue({
         el: '#app',
         data : {
             title: 'Element 元件庫',
             message : '一套為開發者、設計師和產品經理準備的基於 Vue 2.0 的桌面端元件庫。'
         },
         methods : {
             goDocument : function() {
                 window.open('https://element.faas.ele.me/#/zh-CN', '_blank');
             }
         }
     });
    
  5. src目錄下建立index.htm檔案,並在設計應用程式的使用者介面時使用 Element 元件庫中的元件標籤。至於該元件庫中有多少可用的元件以及這些元件所對應的標籤,讀者可以自行查閱其官方文件[^4]。我們在這裡只是簡單示範了Card元件和Button元件的使用方法,為的是證明元件庫已經被成功引入到專案中,具體程式碼如下:

     <!DOCTYPE html>
     <html lang="zh-cn">
         <head>
             <meta charset="UTF-8">
             <!-- 在正式使用 Element 元件之前,請務必要記得載入其樣式檔案。 -->
             <link rel="stylesheet"
                 href="../node_modules/element-ui/lib/theme-chalk/index.css">
             <title>Vue 元件實驗(7):引入第三方元件庫</title>
         </head>
         <body>
             <div id="app">
                 <h1>引入第三方元件庫</h1>
                 <el-card shadow="always">
                     <h2> {{ title }} </h2>
                     <p> {{ message }} </p>
                     <el-button type="info" @click='goDocument'>
                         檢視官方文件
                     </el-button>
                 </el-card>
             </div>
         </body>
     </html>
    
  6. 用瀏覽器訪問public目錄下的index.html檔案,就可以看到最後的結果了,如下圖所示:

    引入第三方元件

需要特別說明的是,我們在這裡只是簡單地介紹瞭如何在一個基於 Vue.js 框架的前端專案中引入第三方元件庫。至於在實際生產環境中是否真的就使用 Element 元件庫,還是選擇別的元件庫,還是要根據專案的實際需求和這些元件庫的具體特性來做決定。在後續具體的專案實踐中,我們將陸續演示如何使用這些第三方元件庫設計出更復雜、更符合實際需求的使用者介面。

相關文章