Vue.js 學習筆記之四:Vue 元件基礎

凌傑發表於2020-10-12

到目前為止,這個系列的筆記所展示的都是一些極為簡單的單頁面 Web 應用程式,並且頁面上通常只有幾個簡單的互動元素。但在實際生產環境中,Web 應用程式的使用者介面往往是由多個複雜的頁面共同組成的。這時候,我們就需要開始注意程式碼的可複用性了,針對這個問題,Vue.js 框架提出的解決方案就是先將使用者介面上的元素按照不同的功能劃分成一個個獨立的元件,例如導航欄、公告欄、資料表格、使用者登錄檔單、使用者登入介面等。這樣一來,我們在之後的工作中就可以像玩樂高玩具一樣,根據需要將這些元件組合成各種具體的應用程式了。總而言之,元件系統是我們在學習 Vue.js 框架中必須要掌握的一個重要概念。下面,這篇筆記將通過編寫一系列實驗示例來體驗一下在 Vue.js 框架中構建和使用元件的基本方法。

在所有實驗開始之前,我需要先在code目錄中建立一個名為00_test的目錄,以便用於存放接下來的一系列實驗專案,由於這些專案只能用於體驗 Vue 元件的構建與使用方法,並沒有實際的應用功能,所以我給了它00這個編號。那麼,下面就來開始第一個實驗吧!為此,我需要繼續在code/00_test目錄中再建立一個名為component_1的實驗目錄,並在該目錄下執行npm install vue命令來安裝 Vue.js 框架。最後,我只需在code/00_test/component_1目錄下建立一個名為index.htm的檔案,並輸入如下程式碼:

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA  -Compatible" content="ie=edge">
    <title>學習 vue 元件實驗(1):元件註冊</title>
`</head>
<body>
    <div id="app">
        <say-hello :who="who"></say-hello>
        <welcome-you :who="who"></welcome-you>
    </div>
    <script src="./node_modules/vue/dist/vue.js"></script>
    <script>
        // 全域性元件註冊
        Vue.component('say-hello', {
            template: `<h1>你好, {{ you }}!</h1>`,
            props: ['who'],
            data: function() {
                return {
                    you: this.who
                };
            }
        });

        const app = new Vue({
            el: '#app',
            // 區域性元件註冊
            components: {
                'welcome-you': {
                    template: `<h2>歡迎你, {{ you }}!</h2>`,
                    props: ['who'],
                    data: function() {
                        return {
                            you: this.who
                        };
                    }
                }
            },
            data: {
                who: 'vue'
            }
        });
    </script>
</body>
</html>

在上述實驗中,我用兩種不同的方式分別建立並註冊了say-hellowelcome-you兩個元件。接下來就藉由這兩個元件來介紹一下這兩種元件的使用。首先是say-hello元件,該元件是通過呼叫Vue.component()方法來建立並註冊到應用程式中的,使用該方法建立的元件通常被稱之為"全域性元件",我們在呼叫它的時候需要提供兩個引數:

  • 第一個引數應該是一個字串物件,用於指定元件的名稱,該名稱也是我們要在 HTML 文件中使用的自定義標籤元素,而由於 HTML 程式碼是大小寫不敏感的,所以我個人會建議大家在給元件起名字的時候應該儘量一律使用小寫字母,單詞之間可以使用-這樣分隔符進行區隔。

  • 第二個引數應該是一個 JavaScript 物件,用於設定元件的各項具體引數。這裡定義了以下三項最基本引數:

    • template:該引數是個字串物件,用於指定該元件的 HTML 模版程式碼,需要注意的是,這段程式碼說對應的 DOM 物件必須有且只能有一個根節點。而這個物件在最終的 HTML 文件中將會由該元件所對應自定義標籤所代表,在這裡就是<say-hello>
    • props:該引數是一個字串陣列,該陣列中的每個元素都是該元件所對應的自定義標籤的一個屬性,該元件的使用者可以通過v-bind指令將該屬性繫結到某一資料上,以便將資料傳到元件內部。例如在這裡,我在<say-hello>標籤中就用v-bind指令將該標籤的who屬性繫結到了 Vue 例項物件的who資料上,並將其傳進say-hello元件中。
    • data:該引數是一個函式,用於設定元件自身的資料,例如這裡的you,我將從呼叫者那裡獲取的who資料賦值給了它。對於後者,我們可以用this引用來獲取。

    當然了,除了上面三個基本引數之外,我們還可以為元件設定更多引數,例如自定義事件及其處理函式等,這些我將會在後續的程式編寫體驗中展示。

下面,我們再來看welcome-you元件的構建。如你所見,該元件是在 vue 例項的components成員中構建並註冊到應用程式中的,使用該方法建立的元件通常被稱之為"區域性元件"(它與全域性元件的區別是,全域性元件會在程式執行時全部載入,而區域性元件只會在被實際用到時載入) 。該components成員的值也是一個 JSON 格式的資料物件,該資料物件中的每一個成員都是一個區域性元件,這些元件採用鍵/值對的方式來定義,鍵對應的是元件的名稱,值對應的是元件引數的設定。當然了,由於區域性元件的命名規則與具體引數的設定方法都與全域性物件一致,這裡就不再重複說明了。

需要注意的是,第一個實驗專案的編寫方式將 HTML 程式碼、Vue 例項的構建程式碼以及元件的構建程式碼糅合在了一起,這對於提高程式碼的可複用性這個目的來說,顯然是不行的。要想解決這個問題,我們可以利用 ES6 規範新增的模組規則將這三部分程式碼隔離開來。為了體驗這種用法,我繼續開始了第二個實驗。具體做法就是在code/00_test目錄中再建立一個名為component_2的實驗目錄,並在該目錄下執行npm install vue命令來安裝 Vue.js 框架。最後,我只需在code/00_test/component_2目錄下建立一個名為index.htm的檔案,並輸入如下程式碼:

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <script src="./node_modules/vue/dist/vue.js"></script>
    <script type="module" src="./main.js"></script>
    <title>學習 vue 元件實驗(2):以 ES6 模組的方式註冊元件</title>
</head>
<body>
    <div id="app">
        <say-hello :who="who"></say-hello>
    </div>
</body>
</html>

在上述 HTML 程式碼中,我們在照常引入 vue.js 框架之後,使用模組的方式引入了main.js指令碼檔案,最好在<div id="app">標籤中使用了後面將要定義的元件所對應的自定義標籤。接下來,我只需要在相同的目錄下建立一個名為main.js的 JavaScript 指令碼檔案,並在其中輸入如下程式碼:

// import Vue from './node_modules/vue/dist/vue.js';
import sayhello from './sayhello.js';

const app = new Vue({
    el: '#app',
    components: {
        'say-hello': sayhello
    },
    data: {
        who:'vue'
    }
});

在上述 JavaScript 程式碼中,我首先使用了 ES6 新增的import-from語句匯入了後續要在sayhello.js檔案中構建的元件,然後在構建 Vue 例項時將其註冊成了區域性元件。最後,我只需在同一目錄下再建立這個sayhello.js指令碼檔案,並在其中輸入如下程式碼:

const tpl = `
    <div>
        <h1>你好, {{ you }}!</h1>
        <input type="text" v-model="you" />
    </div>
`;

const sayhello = {
    template: tpl,
    props : ['who'],
    data : function() {
        return {
            you: this.who
        }
    }
};

export default sayhello;

在這部分程式碼中,我先定義了一個區域性元件,然後再使用 ES6 新增的export default語句將其匯出為模組。當然了,考慮到各種 Web 瀏覽器對 ES6 規範的實際支援情況,以及 Vue.js 框架本身使用的是 CommonJS 模組規範,所以上述實驗依然可能不是編寫 Vue.js 專案的最佳方式,其中可能還需要配置 babel 和 webpack 這樣的轉譯和構建工具來輔助。當然了,如果大家不想陷入如此複雜的配置,那使用 Vue 官方提供的 vue-cli 腳手架工具是一個不錯的選擇,在下一篇筆記中,我就來記錄如何使用這個工具來構建具體的 vue 應用程式。

相關文章