使用Vue組件的注意事項

1.Vue組件名推薦使用大駝峯命名法

爲什麼我們一直在強調 Vue 組件命名使用大駝峯呢???

在此之前,我們對 Vue 組件已經有啦一定的瞭解,我們也知道局部組件的使用頻率會高於全局組件,推薦使用大駝峯命名也和我們局部組件的使用有關,接下來我們慢慢分析.

我們先寫一個簡單的組件來觀察一下:

 <div id="app">
        <!--  在註冊了局部組件的實例中使用局部組件    -->
        <my-component></my-component>
    </div>
    <script>
        // 1.創建劇組件選項對象
        let MyComponent = ({
            template:`
                <div>
                    <h3>我是組件1</h3>
                </div>
            `
        })

        let vm = new Vue({
            el:"#app",
            //2. 將選項對象註冊爲局部組價
            components:{
                "my-component":MyComponent,
            }
        })
    </script>

在上面的代碼中:

  1. 首先定義了一個選項對象 mycomponent,
  2. Vue 的實例化對象中將該實例化對象定義爲了一個局部組件
  3. 在html模板中通過標籤<my-component></my-component> 使用局部組件

在上面的例子中,我們並沒有使用駝峯命名法,但是組件一件可以正常使用.

那麼我們看下面的兩點:

  1. 定義選項對象的時候使用的變量名不能包含連字符,這是標識符的命名規則,毫無疑問,如果我們非要在定義選項對象的時候使用連字符,那麼就必須加引號;
  2. 在上面的代碼中,我們在 Vue 的實例化對象中註冊組件的時候, componnets 選項中是一個對象, my-component 時我們後面要使用的組件名稱, MyComponent 就是我們要註冊爲組件的選項對象.

如果我們的選項對象和組件名相同會發生什麼事呢,在es6中我們知道,如果對象中的屬性名和屬性值相同的時候,我們就可以簡寫,想下面這樣:

const vm = new Vue({
   el:"#app",
   components: {
   //普通寫法
       MyComponent: MyComponent
    //es6的寫法
       MyComponent
   }
})

所以有沒有發現我們爲什麼要腿甲使用駝峯命名法,從這裏就可以看出來了吧.

當我們定義組件的選項對象的時候使用駝峯命名,就是說和需要被註冊爲組件的選項對象和組件名字一致的時候,註冊組件將會變得很簡單.

但是我們通常不會只註冊一個組件,當我們需要註冊多個組件的時候,就可以按照下面這種寫法:

 let vm = new Vue({
            el:"#app",
            //2. 將選項對象註冊爲局部組價
            components:{
               first,second,three
            }
        })

怎麼樣,代碼有沒有變得比以前優雅很多.

總結:
1. 定義組件時最好使用駝峯命名
2. 註冊組件的時候,最好讓組件名和即將被註冊爲組件的選項對象名稱一致
3. 在 html 總使用組件的時候使用連字符

2.template選項

雖然有語法糖簡化了組建的註冊,但是在 template 選項中拼接 HTML 元素依舊比較麻煩,這也導致了 htmlJavaScript 的耦合性太高.

Vue.js提供了兩種方法將定義在 JavaScript 中的 html 分離出來.

2.1 使用 Script 標籤分離

使用 script 標籤分離 JavaScript 內的 html 的內容,此時 script 標籤內會有一個 id 屬性,通過這個 id 關聯.

 <div id="app">
        <my-component></my-component>
    </div>
    <script id="myCom" type="text/x-template">
        <div>
            <h3>我是組件1</h3>
        </div>
    </script>
    <script>
        let MyComponent = ({
            template:"#myCom"
        })

        let vm = new Vue({
            el:"#app",
            components:{
                MyComponent,
            }
        })

儘管我們可以使用 script 標籤將 html 的內容分離出來,但是要注意在 script 標籤內的 type 值的選擇.
使用這種方式後,此時的 template 已經不再是一個 html 模板了.而是一個 id 值,Vue.js 根據這個 id 查找對應的元素,然後將這個元素內的 HTML 作爲模板進行編譯。

注意的點:
使用<script> 標籤時,type指定爲text/x-template,意在告訴瀏覽器這不是一段js腳本,瀏覽器在解析HTML文檔時會忽略<script>標籤內定義的內容。

2.2 使用 template 標籤分離

如果我們選擇使用 template 標籤來分離模板,那麼就只需要指定 id 的值,不再需要 type 屬性.
示例代碼如下:

 <div id="app">
        <my-component></my-component>
    </div>
    <template id = "MyCom">
        <div>
            <h3>我是組件1</h3>
        </div>
    </template>
    <script >
        let MyComponent = ({
            template:"#MyCom"
        })

        let vm = new Vue({
            el:"#app",
            components:{
                MyComponent,
            }
        })
    </script>

在我們已經瞭解了組件基本使用之後,選擇使用 script 標籤或者是 template 標籤來分離內容這種方式會更好一些,折讓我們的 html 代碼和 JavaScript 代碼之間是相互分離的,更有利於我們的維護.

3. 組件選項中的特例

組件中的選項基本與實例選項對象一致, 但是有兩個選項是特例,分別爲el 和 data 屬性.
這兩個選項在在選項對象和實例對象中的使用方式是不同的.

3.1 組件選項中沒有el

el 屬性在實例對象中的作用我們是瞭解的,他用來綁定我們的 Vue 實例將來要接管的 DOM 元素,而我們的組件是在實例中使用的,所以並不需要指定 el.

如果我們強行爲它綁定 el 則會報錯.所以要記住的是組件的選項對象中沒有 el 屬性.

3.2 組件中的data屬性爲什麼是一個函數???

組件中的data選項必須是一個函數,返回一個數據對象

他爲什麼不是和vue的實例化選項中一樣是一個函數呢?我們看下面的內容

3.2.1 組件中的data是對象的情況

不能使用對象的原因:

  1. 組件中會被重複多次調用
  2. 而對象是引用數據類型,如果組件數據使用對象的話,那麼組件所有的複用都共享這些數據.

看下面的代碼:

<div id="app">
    <my-component></my-component>
    <my-component></my-component>
    <my-component></my-component>
</div>
<template id = "MyCom">
    <div>
        <h3>我是組件{{num}}</h3>
        <button @click="add">點擊數字會增加哦</button>
    </div>
</template>
<script >
    //在這種情況下點擊一下,所有的數組都會增加,這不符合我們的目的,我們希望的結果是這些數據之間是不要互相干擾的
    let data = {
        num:1,
    }
    let MyComponent = ({
        template:"#MyCom",
    //在組件的data中直接寫對象是會報錯的,所以我們通過data函數中return出的對象來模擬data的值爲對象的情況
        data:function () {
            return data;
        },
        methods:{
            add() {
                this.num++
            }
        }
    })
    let vm = new Vue({
        el:"#app",
        components:{
            MyComponent,
        }
    })

在這裏插入圖片描述

當我點擊其中的任何一個按鈕時,每一個的數字都會增加,原因是這三個組件共用了一個數據對象,所以當數據對象中的數據一旦發生改變,那麼所有使用了這個數據的地方都會跟着改變.

一些說明的點:

  1. 如果直接在選項對象的 data 中定義一個對象就會報錯
  2. 因此我們使用 returndata 中的對象提取出來,以這樣的方式讓所有的組件共用一個數據對象

通過案例我們就會發現如果所有的組件都共享數據,當有一個組件中的數據發生了變化,所有的組件顯示的數據都會發生變化, 這不是我們想要的.我們想要的是每個數據之間不會相互影響.

3.2.2 組件中的data是函數的情況

所以組件的 data 數據屬性纔會需要函數,每次初始化化的時候都會執行函數,將返回的結果作爲組件的數據,

這樣每次執行函數都會給每個組件創建一個獨立的數據

實例代碼如下:

<div id="app">
    <my-component></my-component>
    <my-component></my-component>
    <my-component></my-component>
</div>
<template id = "MyCom">
    <div>
        <h3>我是組件{{num}}</h3>
        <button @click="add">點擊數字會增加哦</button>
    </div>
</template>
<script >
    // data是個函數,每次執行都會返回新的數據
    //當其中某一個組件的數據發生改變的時候並不會影響其他的組件
    let MyComponent = ({
        template:"#MyCom",
        data() {
            //函數每次執行都會返回一個新的數據,這個數據並不是共享數據
            return {
                num : 1
            }
        },
        methods : {
            add() {
                this.num++
            }
        }
    })
    let vm = new Vue({
        el:"#app",
        components:{
            MyComponent,
        }
    })

在這裏插入圖片描述
當我點擊按鈕的時候,只會有自己的數據發生變化,其他的組的數據並不會發生變化,這是因爲雖然我們對組件進行了複用,但是每次複用的組件都有自己的數據對象,因此在數據上並不會相互影響.

一個組件數據發生改變的時候, 其他組件的數據不會變化,因爲每個組件都有自己獨立的數據.

4.組件的使用問題

通過上面上的例子我們已經瞭解了組件的使用,就是把組件名當做自定義標籤使用,但是這種使用方法有的時候也會出現問題.

看下面的內容就會了解:

4.1 組件標籤解析錯誤

示例代碼如下:

 <div id="app">
     <table>
         <my-component></my-component>
     </table>
   </div>

   <template id = "MyCom">
       <tr>
           <td>內容</td>
           <td>123</td>
       </tr>
   </template>
   <script>
       let MyComponent =({
           template:"#MyCom",
       })
       let vm = new Vue({
           el:"#app",
           components:{
               MyComponent,
           }
       })
   </script>

在這裏插入圖片描述
雖然按照我們的想法實現了,但是有沒有發現, tr 標籤竟然在 table 標籤的外面,
我們使用這個組件的目的就是希望在 table 標籤中渲染 tr 標籤,結果他跑去外面了…

原因在與瀏覽器規範中 table 標籤裏面必須放 tr 標籤,但是我們放的是 my-component自定義標籤,所以在解析的時候就會出問題.

當使用 DOM 作爲模板時 (例如,使用 el 選項來把 Vue 實例掛載到一個已有內容的元素上),你會受到 HTML 本身的一些限制,因爲 Vue 只有在瀏覽器解析、規範化模板之後才能獲取其內容。

尤其要注意,像<ul><ol><table><select> 這樣的元素裏允許包含的元素有限制,而另一些像 <option> 這樣的元素只能出現在某些特定元素的內部。通俗一點講,就是“龍生龍,鳳生鳳,老鼠的兒子會打洞.

特殊的一下父元素如<ul><ol><table><select>裏面不能包含不屬於它的子元素,而與之相對應的<li><tr><option>只可以出現在特定的父元素裏面。

4.2 通過is屬性使用組件

vue允許我們使用 is屬性來使用組件, is 屬性的值是組件名

所以可以採用 is 屬性來制定組件

<div id="app">
    <table>
        <tr is="my-component"></tr>
        <tr is="my-component"/>
        <tr is="my-component"/>
    </table>
</div>

<template id = "MyCom">
    <tr>
        <td>姓名</td>
        <td>學號</td>
        <td>性別</td>
    </tr>
</template>
<script>
    let MyComponent =({
        template:"#MyCom",

    })

    let vm = new Vue({
        el:"#app",
        components:{
            MyComponent,
        }
    })
</script>

此時我們就會發現不僅結果沒問題, 編譯後標籤的嵌套也沒有什麼問題,

因爲我們是按照標準在 tbody 標籤中使用的是 tr 標籤,只不過通過 is 屬性將tr標籤替換爲了組件 my-component 的模板標籤.

此時 tr標籤中沒有嵌套內容,所有使用單標籤,雙標籤都可以

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章