1. 程式人生 > >VUE構建元件(轉載)

VUE構建元件(轉載)

一、vue元件的概念

官方定義:元件(Component)是 Vue.js 最強大的功能之一。元件可以擴充套件 HTML 元素,封裝可重用的程式碼。在較高層面上,元件是自定義元素, Vue.js 的編譯器為它新增特殊功能。在有些情況下,元件也可以是原生 HTML 元素的形式,以 is 特性擴充套件。

博主理解:Vue裡面的元件可以理解為通過對普通html標籤的封裝,得到一套獨立而且可以通用的html標籤,我們在頁面裡面使用這些標籤傳入相應的引數即可呼叫封裝好的元件。通過下面這張圖相信可以一目瞭然。

由普通的html標籤form、input、button、label組成了一個新的元素集合,我們命名為i-form,這個i-form就是vue裡面元件的概念。我們在頁面裡面使用<i-form></i-form>時,通過vue的元件渲染機制,在瀏覽器裡面最終就可以顯示成為普通的html標籤form、input、button、label。

二、元件原理

通過上圖我們知道,vue裡面的元件實際上就是一些普通html元素的集合。那麼,它是如何將這些自定義標籤轉換為普通html標籤的呢?在介紹元件原理之前,還是先來看一個最簡單的元件例項。

    <div style="text-align:center;margin-top:200px;" id="app">
        <!-- 3. 在Vue例項裡面使用元件-->
        <b-component></b-component>
    </div>

    <script src="Content/vue/dist/vue.js"></script>
    <script type="text/javascript">
        // 1.建立元件構造器
        var myComponent = Vue.extend({
            template: '<div id="bComponent">我是自定義元件的內容</div>'
        });

        //2.註冊元件到vue裡面
        Vue.component('b-component', myComponent)

        new Vue({
            el: '#app',
        });
        
    </script>

 

整個過程不難理解,主要分為三個大的步驟:

  1. 定義一個元件構造器,宣告元件要渲染的html內容
  2. 將元件構造器註冊到Vue的元件系統裡面,使其成為Vue的一個元件,給元件取一個名稱,比如b-component
  3. 在Vue的例項裡面使用元件。因為上面兩步定義了Vue的元件,既然是Vue的元件,那麼要使用元件,首先得有一個Vue的例項,元件必須要在Vue的例項裡面使用。

整個過程:

其實有時為了簡便,我們常將1、2步合併,程式碼如下:

    <div style="text-align:center;margin-top:200px;" id="app">
        <!-- 2. 在Vue例項裡面使用元件-->
        <b-component></b-component>
    </div>

    <script src="Content/vue/dist/vue.js"></script>
    <script type="text/javascript">
        //1.建立元件構造器,註冊元件到vue裡面
        Vue.component('b-component', {
            template: '<div id="bComponent">我是自定義元件的內容</div>'
        })

        new Vue({
            el: '#app',
        });
        
    </script>

三、元件的使用

上述解釋了下元件的定義和原理,關於元件的簡單實用,我們主要介紹以下幾個方面。

(1)元件的作用域

這個應該不難理解,元件分為全域性元件和區域性元件,也就是說,你可以在頁面上面定義一個全域性元件,頁面上面的任何Vue例項都可使用;而對於區域性元件,是和具體的Vue例項相關的,只能在當前Vue例項裡面使用元件。還有一點需要說明:元件必須在Vue的例項裡面使用,在Vue例項之外使用元件無效。通過下面一個例子即可清晰說明它們的區別。

<body>
    <div style="text-align:center;margin-top:50px;" id="app">
        <b-component></b-component>
        <b-component2></b-component2>
    </div>
    <div style="text-align:center;margin-top:50px;" id="app2">
        <b-component></b-component>
        <b-component2></b-component2>
    </div>

    <b-component></b-component>
    <b-component2></b-component2>
   
    <script src="Content/vue/dist/vue.js"></script>
    <script type="text/javascript">

        //定義元件
        Vue.component('b-component', {
            template: '<div id="bComponent">我是全域性元件,任何Vue例項都可使用</div>'
        })

        new Vue({
            el: '#app',
            components: {
                'b-component2': {
                    template: '<div id="bComponent">我是區域性元件,只能在app這個div裡面使用</div>'
                }
            }
        });
        new Vue({
            el: '#app2',
        });
        
    </script>
</body>

(2)元件的傳值

元件例項的作用域是孤立的。這意味著不能並且不應該在子元件的模板內直接引用父元件的資料。可以使用 props 把資料傳給子元件。這段話怎麼理解呢?我們先來看幾個例子。

  • 靜態Prop

我們先來看看下面的一段簡單的程式碼

<body>
    <div style="text-align:center;margin-top:50px;" id="app">
        <b-component componentmessage="你好"></b-component>
    </div>
   
    <script src="Content/vue/dist/vue.js"></script>
    <script type="text/javascript">
        Vue.component('b-component', {
            template: '<div>{{componentmessage}}</div>',
            props: ['componentmessage'],
        })

        new Vue({
            el: '#app'
        });
    </script>
</body>

通過在元件裡面使用props屬性,將外部的值傳入元件模板。最終渲染到頁面上面就得到“<div>你好</div>”這麼一段html

  • 動態Prop

在多數情況下,我們在使用Vue例項的時候,一般通過data屬性傳入模型,這個時候,我們的name和age如何傳到元件例項裡面呢?如下:

<body>
    <div style="text-align:center;margin-top:50px;" id="app">
        <b-component v-bind:my-name="name" v-bind:my-age="Age"></b-component>
    </div>
    <script src="Content/vue/dist/vue.js"></script>
    <script type="text/javascript">
        Vue.component('b-component', {
            template: '<div>姓名:{{myName}},年齡:{{myAge}}</div>',
            props: ['myName', 'myAge'],
        })

        new Vue({
            el: '#app',
            data: {
                name: 'Jim',
                Age: '28'
            }
        });
    </script>
</body>

需要說明幾點:

  • 在使用標籤<b-component>的時候,通過v-bind命令,將Vue例項裡面的name、Age屬性以別名my-name、my-age的形式傳入元件例項。
  • 為什麼my-name、my-age傳到元件裡面就變成了['myName', 'myAge']呢?這是因為在子元件中定義prop時,使用了camelCase命名法。由於HTML特性不區分大小寫,camelCase的prop用於特性時,需要轉為 kebab-case(短橫線隔開)。
  • 很多情況下,v-bind可以簡寫為冒號(:),所以上述程式碼也可以這麼寫: <b-component :my-name="name" :my-age="Age"></b-component> 。效果也是一樣。
  • 這裡很噁心的還有一點,在Props裡面定義的必須要使用所謂“駝峰式”的方式來定義變數,否則會因為一個變數名大小寫搞死你。比如props:["myName"]這樣可以正確,但是如果props:["myname"]這樣的話就錯誤,使用myname取值會是undefined。博主第一次玩這個玩意找了好半天,新手一定注意,大坑,大坑,大坑!慎入!

在封裝元件裡面,props屬性使用非常多,更多props用法可參見文件https://vuefe.cn/v2/guide/components.html#Prop

(3)元件的插槽

在使用元件的時候,我們經常需要在元件例項向元件模板傳入html元素,這個時候我們就需要在元件的模板標籤裡面留一些佔位符(俗稱“坑”),然後在具體的元件例項裡面傳入標籤來填“坑”,在Vue裡面這些“坑”也叫插槽,使用<slot>來解決。對於開發人員來說,這個其實不陌生,從原來的母版頁到現在的layout頁面,基本都是使用的這種原理。

<body>
    <div style="text-align:center;margin-top:50px;" id="app">
        <b-component>
            <h1 slot="header">這裡可能是一個頁面標題</h1>
            <h2 slot="content">姓名:{{name}},年齡:{{Age}}</h2>
            <h1 slot="footer">尾部</h1>
        </b-component>
    </div>
    <template id="slottest">
        <div class="container">
            <header>
                <slot name="header"></slot>
            </header>
            <main>
                <slot name="content"></slot>
            </main>
            <footer>
                <slot name="footer"></slot>
            </footer>
        </div>
    </template>
   
    <script src="Content/vue/dist/vue.js"></script>
    <script type="text/javascript">

        Vue.component('b-component', {
            template: '#slottest',
        })

        new Vue({
            el: '#app',
            data: {
                name: 'Jim',
                Age: '28'
            }
        });
    </script>
</body>

上述程式碼應該不難理解,就是一個“挖坑”和“填坑”的過程。順便要提一筆的是,Vue的元件支援使用<templete>的模式來定義標籤模板,使用更加靈活和方便。