Vue 2 | Part 7 組件

界面寫多了,你們應該都會想到一個問題:JS的模塊寫好之後能夠在多個地方重複使用,HTML有沒有辦法作到呢?Vue給了咱們這個能力,使用組件,就能夠輕鬆作到。javascript

最簡單的組件

初始化Vue實例以前,使用Vue.component方法註冊一個簡單的template,在HTML中,就能夠直接使用。由於這裏會舉一連串的例子,就直接用onetwothree來做爲組件名稱了。css

<body>
    <div id="app">
        <one></one>
    </div>
</body>
Vue.component('one', {
    template: '<li>這是一個item</li>'
})

var app = new Vue({
    el: '#app'
})

component-one

組件名稱定義的時候有一點須要注意的,就是要使用中劃線分詞。比方說,我想新建一個叫list item的組件,組件的名稱就須要是list-item,在HTML中使用的時候也同樣:html

<div id="app">
    <list-item></list-item>
</div>
Vue.component('list-item', {
    template: '<li>這是一個item</li>'
})

組件的內容能夠從數據獲取嗎?

能夠。在組件的data方法裏面返回數據就能夠了。跟Vue實例不同的是,組件的data對應一個function,在組件中想要用到的數據,須要從這個方法裏面返回(返回的數據類型是對象)。vue

<div id="app">
    <two></two>
</div>
Vue.component('two', {
    template: '<li>{{ listItem.name }}</li>',
    data: function () {
        return {
            // 在html中引入gamesDB.js
            listItem: window.games[0]
        }
    }
})

component-two

組件的內容能夠在HTML裏面定義嗎?

能夠。在組件中使用<slot>吧。在HTML的組件中間定義的內容,就會被插入到<slot> tag的位置中去。除了直接定義文字以外,固然也能夠寫HTML。java

<div id="app">
    <three>item1</three>
    <three>item2</three>
    <three>item3</three>
</div>
Vue.component('three', {
    template: '<li><slot></slot></li>'
})

component-three

在沒有定義組件內容的時候,能夠有默認的內容嗎?

能夠。在<slot>tag中間設置的內容,就是默認的內容。git

<div id="app">
    <four></four>
    <four>這是自定義的內容</four>
</div>
Vue.component('three', {
    template: '<li><slot>默認內容</slot></li>'
})

component-four

若是我想在不一樣的位置插入不一樣的內容呢?

使用具名<slot>吧。在template裏面設置好每一個slot的名稱,在HTML中經過slot屬性指定內容要插入到哪一個具名<slot>中。詳情請看下面的代碼片斷和註釋。github

<div id="app">
    <five>
        <!-- 指定要插入header這個slot中 -->
        <ul slot="header" class="nav nav-tabs">
          <li class="active"><a href="#">Home</a></li>
          <li><a href="#">Profile</a></li>
          <li><a href="#">Messages</a></li>
        </ul>

        <!-- 指定要插入content這個slot中 -->
        <div slot="content">this is my awesome website</div>
    </five>
</div>
Vue.component('five', {
    template:
        '<div>' +
            '<div class="top-nav">' +
                // 設置slot的名稱爲header
                '<slot name="header"></slot>' +
            '</div>' +
            '<div class="main">' +
                // 設置slot的名稱爲content
                '<slot name="content"></slot>' +
            '</div>' +
        '</div>'
})

component-five-1

圖片中選中的這一行,由於在HTML中指定slot的時候使用了div tag因此文字被它包了起來,若是但願直接插入文字,可使用template這個tag:web

<div id="app">
    <five>
        <ul slot="header" class="nav nav-tabs">
            <!-- ... -->
        </ul>

        <!-- 改成使用template tag -->
        <template slot="content">this is my awesome website</template>
    </five>
</div>

component-five-2

既然組件至關於自定義了一個tag,那能夠自定義tag的屬性嗎?

能夠的。使用componentprops來設置吧。這裏有一點千萬要記得,在props裏面,是駝峯式分詞,可是,在HTML裏面使用這個屬性的時候,須要用中劃線分詞,是中!劃!線!我最開始使用的時候,兩邊都習慣性地使用駝峯,結果死活沒有效果。最後才發現官方文檔有說明……app

<div id="app">
    <six user-name="john"></six>
</div>
Vue.component('six', {
    props: ['userName'],
    template: '<li>{{ userName }}</li>'
})

component-six-1

從屬性傳入的數據,組件內能夠進行處理嗎?

能夠。咱們用計算屬性作例子吧。把屬性設定的文字轉換爲全大寫。ide

<div id="app">
    <six user-name="john"></six>
</div>
Vue.component('six', {
    props: ['userName'],
    // 最後template中使用的是計算屬性
    template: '<li>{{ uppercaseName }}</li>',
    computed: {
        uppercaseName: function() {
            return this.userName.trim().toUpperCase()
        }
    }
})

component-six-2

這些自定義的屬性也能夠用v-bind指令嗎?

YES!直接用官方的一個雙向數據綁定的例子吧:

<div id="app">
    <input type="text" v-model="inputMsg" />
    </br>
    <six :user-name="inputMsg"></six>
</div>
Vue.component('six', {
    props: ['userName'],
    template: '<li>{{ uppercaseName }}</li>',
    computed: {
        uppercaseName: function() {
            return this.userName.trim().toUpperCase()
        }
    }
})

var app = new Vue({
    el: '#app',
    data: {
        inputMsg: ''
    }
})

component-six-3

能夠在組件裏面直接使用另一個組件嗎?

固然能夠。咱們直接上例子吧:

<div id="app">
    <game-list></game-list>
</div>
Vue.component('game-list', {
    template:
        '<ul>' +
            // 直接使用第三個組件進行循環
            '<three v-for="game in games">{{ game.name }}</three>' +
        '</ul>',
    data: function () {
        return {
            games: window.games
        }
    }
})

component-seven

這期的基本上把組件的基礎都過了一遍,視頻裏面會附加套用boostrap的css作一個本身的組件的內容。敬請期待下一期,組件通訊。

寫在最後

源碼地址:https://github.com/levblanc/v...

視頻攻略:小的不才,爲求一讚,自制 本期視頻攻略 在此。

相關文章
相關標籤/搜索