vue.js——基礎篇之vue組件

vue.js——基礎篇之vue組件

一、什麼是組件

      組件(Component)是Vue.js最強大的功能之一。組件可以擴展 HTML元素,封裝可重用的代碼。在較高層面上,組件是自定義元素,vue.js的編譯器爲它添加特殊功能,在有些情況下,組件也可以是原生HTML元素的形式,以is特性擴展。組件系統讓我們可以用獨立可複用的小組件來構建大型應用,幾乎任意類型的應用的界面都可以抽象爲一個組件樹。
      組件系統是Vue的另一個重要概念,因爲它是一種抽象,允許使用小型、獨立和通常可複用的組件構建大型應用。

組件樹

在Vue裏,一個組件本質上是一個擁有預定義選項的一個Vue實例。

這裏寫圖片描述

二、組件與自定義元素的關係

1、Vue組件非常類似於自定義元素,這是因爲Vue的組件語法部分參考了該規範。
2、 Web組件規範仍然處於草案階段,並且未被所有瀏覽器原生實現。相比之下,Vue組件不需要任何polyfill,並且在所有支持的瀏覽器 (IE9 及更高版本) 之下表現一致。必要時,Vue組件也可以包裝於原生自定義元素之內。
3、Vue組件提供了純自定義元素所不具備的一些重要功能,最突出的是跨組件數據流、自定義事件通信以及構建工具集成。

三、註冊全局組件

1、全局組件,所有實例都能用全局組件。

全局組件在註冊之後可以用在任何新創建的Vue根實例(new Vue)的模板中。

2、註冊全局組件

*註冊一個全局組件語法格式如下:
       Vue.component(tagName, options)
*參數說明:
      tagName爲組件名,options爲配置選項。
*註冊後,可使用以下方式來調用組件:
      <tagName></tagName>
*注意:
      組件在註冊後,便可在父實例的模塊中以自定義元素的形式使用,但要確保在初始化根實例之前註冊了組件。

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>註冊全局組件</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <my-component></my-component>
    </div>
    <script>
        //註冊全局組件
        Vue.component('my-component',{
            template:'<div>{{msg}}<input type="button" value="彈" @click="tanchu"/></div>',
            //注意:這裏的data必須是一個函數,和實例中的data不一樣,return返回一個對象
            data:function(){
                return {
                    msg:"Hello vue"
                };
            },
            methods:{
                tanchu:function(){
                    console.log(this.msg);
                }
            }
        });
        //初始化根實例
        new Vue({
            el:"#app"
        });
    </script>
</body>
</html>

註冊全局組件

四、註冊局部組件

    全局註冊往往是不夠理想的。全局註冊所有的組件意味着即便已經不再使用一個組件了,它仍然會被包含在
 最終的構建結果中。這造成了用戶下載的JavaScript的無謂的增加。所以可以在實例選項中註冊局部組件,這
 樣組件只能在這個實例中使用。

*註冊局部組件步驟:
1)通過一個普通的JavaScript對象來定義組件:
        var ComponentA = { }
2)然後在根實例中的components選項中定義想要使用的組件:
new Vue({
        el: ‘#app’,
        components: {
                ‘component-a’: ComponentA
        }
})
*對於components對象中的每個屬性來說,其屬性名就是自定義元素的名字,其屬性值就是這個組件的選項對象。
*注意局部註冊的組件在其子組件中不可用。例如,希望 ComponentA 在ComponentB中可用,則需要這樣寫:
var ComponentA = {};
var ComponentB = {
        components: {
                ‘component-a’: ComponentA
        },
}
*或者如果通過Babel和webpack使用ES2015模塊,那麼代碼看起來更像:
import ComponentA from ‘./ComponentA.vue’
export default {
        components: {
                ComponentA
        },
}
*注意在ES2015+中,在對象中放一個類似ComponentA的變量名其實是ComponentA: ComponentA的縮寫,即這個變量名同時是用在模板中的自定義元素的名稱,包含了這個組件選項的變量名。

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>註冊局部組件</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <my-component></my-component>
    </div>
    <div class="app">
        <my-component></my-component>
    </div>
    <script>
        //註冊局部組件
        var com = {
            template:'<div>{{msg}}<input type="button" value="彈" @click="tanchu"/></div>',
            data:function(){
                return {
                    msg:"Hello"
                };
            },
            methods:{
                tanchu:function(){
                    console.log(this.msg);
                }
            }
        };
        //初始化根實例
        new Vue({
            el:"#app",
            components:{
               'my-component':com
            }
        });
        new Vue({
            el:".app"
            //第二個根實例沒有註冊my-component這個局部組件,會報錯
        });
    </script>
</body>
</html>

五、關於組件名的注意事項

      在註冊一個組件時,始終需要給它一個名字。組件名就是 Vue.component 的第一個參數。當直接在DOM中使用一個組件 (而不是在字符串模板或單文件組件) 的時候,強烈推薦遵循W3C規範中的自定義組件名 (字母全小寫且必須包含一個連字符)。這會避免當前以及未來的HTML元素相沖突。請注意,Vue.js不對自定義標記名稱(全小寫,必須包含連字符)強制執行W3C規則,但按照此慣例被認爲是良好的做法。

定義組件名的方式有兩種:
1)使用kebab-case:Vue.component('my-component-name', {})
   當使用kebab-case(短橫線分隔命名)定義一個組件時,也必須在引用這個自定義元素時使用kebab-case,
   例如<my-component-name>。
2)使用PascalCase:Vue.component('MyComponentName', {})
   當使用PascalCase(駝峯式命名)定義一個組件時,在引用這個自定義元素時兩種命名法都可以使用。
   儘管如此,直接在DOM(即非字符串的模板)中使用時只有kebab-case是有效的。

六、模板解析

      有些 HTML 元素,諸如 ul、ol、table,對於哪些元素可以出現在其內部是有嚴格限制的。而有些元素,諸如 li、tr,只能出現在其它某些特定的元素內部。這會導致使用這些有約束條件的元素時遇到一些問題。這時候自定義組件會被作爲無效的內容提升到外部,並導致最終渲染結果出錯。
is 特性給了一個變通的辦法:
<table>
<tr is=”blog-post-row”></tr>
</table>
需要注意的是如果從以下來源使用模板的話,這條限制是不存在的:
1)字符串 (例如:template: ‘…’)
2)單文件組件 (.vue)
3)<script type=”text/x-template”>

這些限制中最常見的是:

  • a不能包含其他交互元素(例如按鈕和其他鏈接)
  • li應該是直接孩子ul或ol,兩者ul並ol只能包含li
  • option應該是一個直接的孩子select,並且select只能包含option(和optgroup)
  • table只能包含thead,tbody,tfoot和tr,這些元素應該是直接孩子table
  • tr只能包含th和td,而這些元素應該是直接子女的tr

七、組件通訊

1、Prop

    prop是父組件用來傳遞數據的一個自定義屬性。父組件的數據需要通過props把數據傳給子組件,
子組件需要顯式地用props選項聲明"prop":Prop是可以在組件上註冊的一些自定義特性。當一個值
傳遞給一個prop特性的時候,它就變成了那個組件實例的一個屬性。

2、靜態的Prop

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>靜態Prop</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <tip msg="HelloHtml"></tip>
        <tip msg="HelloCss"></tip>
        <tip msg="HelloJavascript"></tip>
    </div>

    <script type="text/x-Template" id="tipTpl">
        <div>
            <input type="button" value="消息彈窗" @click="alterMsg"/>
        </div>
    </script>

    <script>
        var tipTpl = {
            template:'#tipTpl',
            //聲明prop
            props:['msg'],
            methods:{
                alterMsg:function(){
                    console.log(this.msg);
                }
            }
        };
        new Vue({
            el:"#app",
            components:{
               'tip':tipTpl
            }
        });
    </script>
</body>
</html>

靜態prop

3、動態的Prop

可以用v-bind動態綁定props的值到父組件的數據中。每當父組件的數據變化時,該變化也會傳導給子組件。
<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>動態Prop</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <tip v-bind:msg="a"></tip>
        <tip msg="HelloCss"></tip>
        <tip msg="HelloJavascript"></tip>
    </div>

    <script type="text/x-Template" id="tipTpl">
        <div>
            <input type="button" value="消息彈窗" @click="alterMsg"/>
        </div>
    </script>

    <script>
        var tipTpl = {
            template:'#tipTpl',
            //聲明prop
            props:['msg'],
            methods:{
                alterMsg:function(){
                    console.log(this.msg);
                }
            }
        };
        new Vue({
            el:"#app",
            components:{
               'tip':tipTpl
            },
            data:{
                a:'HelloVue'
            }
        });
    </script>
</body>
</html>

動態prop

一個組件默認可以擁有任意數量的 prop,任何值都可以傳遞給任何 prop。在上述模板中,你會發現我們能夠在組件實例中訪問這個值,就像訪問 data 中的值一樣。

一個 prop 被註冊之後,你就可以像這樣把數據作爲一個自定義特性傳遞進來:




然而在一個典型的應用中,你可能在 data 裏有一個博文的數組:

new Vue({
el: ‘#blog-post-demo’,
data: {
posts: [
{ id: 1, title: ‘My journey with Vue’ },
{ id: 2, title: ‘Blogging with Vue’ },
{ id: 3, title: ‘Why Vue is so fun’ },
]
}
})
並想要爲每篇博文渲染一個組件:

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