vue.js組件

有一篇非常棒的關(guān)于vue.js的組件的文章,寫的特別好,特別清楚,容易理解。鏈接:上篇:http://www.cnblogs.com/keepfool/p/5625583.html 下篇:http://www.cnblogs.com/keepfool/p/5637834.html

以下是我學(xué)習(xí)鏈接所對(duì)應(yīng)的這兩篇文章的學(xué)習(xí)摘要。

1.組件的創(chuàng)建和注冊(cè)

1.1 創(chuàng)建組件構(gòu)造器(使用Vue.extend({模板}))

var child = Vue.extend({
    template:'<div>This is my first component!</div>'
})

1.2 注冊(cè)組件:Vue.component({'組件名',組件構(gòu)造器名})

Vue.component('my-component',myComponent)

1.3 使用組件

new Vue({
    el:'#app'
});
<div id="app">//組件需掛載到對(duì)應(yīng)的vue實(shí)例的掛載范圍內(nèi)
    <my-component></my-component>
</div>

1.4 全局注冊(cè)

eg:

<div id="example">
    <my-component></my-component>
</div>

<script>
//注冊(cè),這種是全局注冊(cè)
Vue.component('my-component',{
    template:'<div>A component!</div>'
})
//創(chuàng)建根實(shí)例
new Vue({
    el:'#example'
})
</script>

渲染為:

<div id="example">
<div>A component!</div>
</div>
效果圖

1.5 局部注冊(cè)

eg:

<div id="example">
    <my-component></my-component>
</div>

<script>
var myComponent = Vue.extend( {
    template: '<div>A component!</div>'
})
new Vue({
    el:'#example',
    components: {
        'my-component':myComponent//用實(shí)例選項(xiàng)“components”注冊(cè),局部注冊(cè)
    }
})
</script>
效果圖

1.3 全局注冊(cè)和局部注冊(cè)區(qū)分

在new Vue ()中注冊(cè)的為局部注冊(cè),只能掛到id值與new Vue()中的el值相同的Vue實(shí)例,而在new Vue外注冊(cè)的為全局注冊(cè)的,可以掛到各個(gè)Vue實(shí)例。
eg:

<div id="example">
    <my-component></my-component>
</div>
<div id="example-2">
    <my-component></my-component>//將局部注冊(cè)的組件掛到不對(duì)應(yīng)的組件上,無(wú)法正確顯示
</div>

<script>
var child = {
    template: '<div>A component!</div>'
}
new Vue({
    el:'#example',
    components: {
        'my-component':child//局部注冊(cè)的組件
    }
})
</script>
無(wú)法正確顯示兩句話

eg:

<div id="example">
    <my-component></my-component>
</div>
<div id="example-2">
    <my-component></my-component>//將全局注冊(cè)的組件掛到不同id值的組件上
</div>

<script>
//全局注冊(cè)
Vue.component('my-component',{
    template:'<div>A component!</div>'
})
//創(chuàng)建根實(shí)例
var vm1 = new Vue({
    el:'#example'
})
var vm2 = new Vue({
    el:'#example-2'
})
</script>
正確地顯示了兩行話

2.父組件和子組件

在一個(gè)組件的模板(template)中使用了其他組件,這兩個(gè)組件之間就構(gòu)成了父子關(guān)系,該組件是父組件,父組件的模板中的組件是子組件。

子組件只能在父組件的template中使用。

  • 創(chuàng)建父組件構(gòu)造器
  • 創(chuàng)建子組件構(gòu)造器
  • 注冊(cè)父組件
  • 注冊(cè)子組件
  • 使用組件
<div id="app">
    <parent-component>
    </parent-component>
</div>

<script>
//創(chuàng)建父組件構(gòu)造器,模板中使用了子組件<child-component></child-component>
var parent = Vue.extend({
    template:'<div>This is a parent component!and <child-component></child-component></div>'
})
//創(chuàng)建子組件構(gòu)造器
var child = Vue.extend({
    template:'<div>This is a child component!</div>'
})
//注冊(cè)父組件和子組件
Vue.component('child-component',child)
Vue.component('parent-component',parent)
//vue實(shí)例
new Vue({
    el:'#app'
});
</script>
運(yùn)行結(jié)果

3.組件注冊(cè)語(yǔ)法糖:Vue.js簡(jiǎn)化組件注冊(cè)的過(guò)程

3.1 使用Vue.component()直接創(chuàng)建和注冊(cè)組件:

// 全局注冊(cè),my-component1是標(biāo)簽名稱
Vue.component('my-component1',{
    template: '<div>This is the first component!</div>'
})

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

使用這種方式,Vue在背后會(huì)自動(dòng)地調(diào)用Vue.extend()。

3.2 在選項(xiàng)對(duì)象的components屬性中實(shí)現(xiàn)局部注冊(cè):

var vm2 = new Vue({
    el: '#app2',
    components: {
        // 局部注冊(cè),my-component2是標(biāo)簽名稱
        'my-component2': {
            template: '<div>This is the second component!</div>'
        },
        // 局部注冊(cè),my-component3是標(biāo)簽名稱
        'my-component3': {
            template: '<div>This is the third component!</div>'
        }
    }
})

4. 使用script或template標(biāo)簽:分離js代碼template中的HTML元素

4.1 使用<script>標(biāo)簽

將原本寫在template的內(nèi)容寫在<script type="text/x-template" id="myComponent"></script>標(biāo)簽中,而組件的template的值為<script>標(biāo)簽的“id”值。
Vue.js根據(jù)template里面的id值,找到對(duì)應(yīng)的<script>標(biāo)簽,將標(biāo)簽中的HTML作為模板進(jìn)行編譯。

注意:使用<script>標(biāo)簽時(shí),type指定為text/x-template,意在告訴瀏覽器這不是一段js腳本,瀏覽器在解析HTML文檔時(shí)會(huì)忽略<script>標(biāo)簽內(nèi)定義的內(nèi)容。

<div id="app">
            <my-component></my-component>
 </div>
 <script type="text/x-template" id="myComponent">
      <div>This is a component!</div>
  </script>
<script> 
        Vue.component('my-component',{
            template: '#myComponent'
        })
        
        new Vue({
            el: '#app'
        })        
</script>

4.2 使用<template>標(biāo)簽

<template id="template選項(xiàng)的值">
//這里是原來(lái)寫在template選項(xiàng)中的HTML
</template>

<div id="app">
      <my-component></my-component>
</div>
<template id="myComponent">
      <div>This is a component!</div>
</template>
<script>
     Vue.component('my-component',{
            template: '#myComponent'
        })
        
        new Vue({
            el: '#app'
        })
</script>

建議使用<script>或<template>標(biāo)簽來(lái)定義組件的HTML模板。
這使得HTML代碼和JavaScript代碼是分離的,便于閱讀和維護(hù)。

5. 組件的el和data選項(xiàng)

Vue.extend() 或Vue.component()中的data 和el必須是函數(shù)。
eg:

Vue.component('my-component', {
    data: function(){
        return {a : 1}
    }
})

6.使用props

6.1基礎(chǔ)示例

var vm = new Vue({
    el: '#app',
    data: {
        name: 'keepfool',
        age: 28
    },
    components: {
        'my-component': {
            template: '#myComponent',
            props: ['myName', 'myAge']
        }
    }
})

這個(gè)vue實(shí)例可以看作'my-component'組件的父組件。要使用父組件的數(shù)據(jù)例如'data'就要先在子組件中定義props屬性。在定義屬性的時(shí)候用的是駝峰命名。在使用組件時(shí)引用props屬性的內(nèi)容時(shí)需要轉(zhuǎn)為 kebab-case(短橫線隔開(kāi))命名。
將父組件數(shù)據(jù)通過(guò)已定義好的props屬性傳遞給子組件:

<div id="app">
    <my-component v-bind:my-name="name" v-bind:my-age="age"></my-component>
//"my-name"對(duì)應(yīng)props的"myName","name"對(duì)應(yīng)父組件的數(shù)據(jù)"name","my-age"對(duì)應(yīng)props的"myAge","age"對(duì)應(yīng)父組件的數(shù)據(jù)"age"
</div>

定義子組件的HTML模板:

<template id="myComponent">
    <table>
        <tr>
            <th colspan="2">
                子組件數(shù)據(jù)
            </th>
        </tr>
        <tr>
            <td>my name</td>
            <td>{{ myName }}</td>//在props屬性中定義,將父組件對(duì)應(yīng)的數(shù)值傳遞過(guò)來(lái)
        </tr>
        <tr>
            <td>my age</td>
            <td>{{ myAge }}</td>////在props屬性中定義,將父組件對(duì)應(yīng)的數(shù)值傳遞過(guò)來(lái)
        </tr>
    </table>
</template>

加上自定義的CSS樣式,最終效果圖如下:

Paste_Image.png

在父組件中使用子組件時(shí),通過(guò)以下語(yǔ)法將數(shù)據(jù)傳遞給子組件:
<child-component v-bind:子組件prop="父組件數(shù)據(jù)屬性"></child-component>

6.2 props的綁定類型

6.2.1 單向綁定
  • 修改父組件的數(shù)據(jù)會(huì)影響子組件的數(shù)據(jù);
  • 修改子組件的數(shù)據(jù)不會(huì)影響父組件的數(shù)據(jù)。
6.2.2 雙向綁定

可以在使用子組件時(shí),使用.sync顯式地指定雙向綁定,這使得子組件的數(shù)據(jù)修改會(huì)回傳給父組件。

<child-component v-bind:my-name.sync="name" v-bind:my-age.sync="age"></child-component>
6.2.3 單次綁定

可以使用.once顯式地指定單次綁定,單次綁定在建立之后不會(huì)同步之后的變化,這意味著即使父組件修改了數(shù)據(jù),也不會(huì)傳導(dǎo)給子組件。

<child-component v-bind:my-name.once="name" v-bind:my-age.once="age"></child-component>

6.3 props驗(yàn)證

props: {
    data: Array,
    columns: Array,
    filterKey: String
}

這段代碼表示:父組件傳遞過(guò)來(lái)的data和columns必須是Array類型,filterKey必須是字符串類型。

7. 解決IE不支持<template>標(biāo)簽

IE不支持<template>標(biāo)簽,所以<template>標(biāo)簽中的內(nèi)容在IE瀏覽器中會(huì)被顯示出來(lái),所以要將<template>的display設(shè)置為none。

template{
    display: none;
}

8. 使用slot:內(nèi)容分發(fā)

8.1 單個(gè)slot

<div id="app">
    <my-component>
        <h1>Hello vue.js!</h1>
    </my-component>
    <my-component></my-component>
</div>
<template id="temp">
    <h2>this is a component!</h2>
    <slot>slot</slot>
</template>
<script type="text/javascript">
    var vm = new Vue({
        el:'#app',
        components:{
            'my-component':{
                template:'#temp',
            }
        }
    })
</script>

<template>標(biāo)簽中的<slot>,如果在使用該組件的時(shí)候,組件中包含了其他內(nèi)容,就會(huì)替換掉<slot>的內(nèi)容,如果組件沒(méi)有包含其他內(nèi)容,<slot>中的內(nèi)容就會(huì)直接顯示。組件中包含的內(nèi)容叫做分發(fā)的內(nèi)容。

Paste_Image.png
8.2 多個(gè)slot:指定名字,對(duì)應(yīng)slot
<div id="app">
    <my-component>
    <div slot="slot1">
        <h1>Hello slot1!</h1>
    </div>
    <div slot="slot2">
        <h1>Hello slot2!</h1>
    </div>
    <div slot="slot3">
        <h1>Hello slot3!</h1>
    </div>  
    </my-component>
    <my-component></my-component>
</div>
<template id="temp">
    <h2>this is a component!</h2>
    <slot name="slot1">slot1</slot>
    <slot name="slot2">slot2</slot>
    <slot name="slot3">slot3</slot>
</template>
<script type="text/javascript">
    var vm = new Vue({
        el:'#app',
        components:{
            'my-component':{
                template:'#temp',
            }
        }
    })
</script>
Paste_Image.png
運(yùn)行結(jié)果

9.父子組件之間的訪問(wèn)

9.1父組件訪問(wèn)子組件

9.1.1 $children
父組件.$children[i]
9.1.2 $refs

在子組件上使用v-ref指令,可以給子組件指定一個(gè)索引ID:

<template id="parent-component">
    <child-component1 v-ref:cc1></child-component1>
    <child-component2 v-ref:cc2></child-component2>
    <button v-on:click="showChildComponentData">顯示子組件的數(shù)據(jù)</button>
</template>

在父組件中,則通過(guò)$refs.索引ID訪問(wèn)子組件的實(shí)例:

showChildComponentData: function() {
    alert(this.$refs.cc1.msg);
    alert(this.$refs.cc2.msg);
}

9.2 子組件訪問(wèn)父組件

alert(子組件.$parent.msg)

10.自定義事件

10.1 派發(fā)事件$dispatch()

<div id="app">
    <p>Messages: {{ messages | json }}</p>
    <child-component></child-component>
</div>
<template id="child-component">
    <input v-model="msg" />
    <button v-on:click="notify">Dispatch Event</button>
</template>
<script src="js/vue.js"></script>
<script>
    // 注冊(cè)子組件
    Vue.component('child-component', {
        template: '#child-component',
        data: function() {
            return {
                msg: ''
            }
        },
        methods: {
            notify: function() {
                if (this.msg.trim()) {
                    this.$dispatch('child-msg', this.msg)
                    this.msg = ''
                }
            }
        }
    })
    // 初始化父組件
    new Vue({
        el: '#app',
        data: {
            messages: []
        },
        events: {
            'child-msg': function(msg) {
                this.messages.push(msg)
            }
        }
    })
</script>
  • 子組件的button元素綁定了click事件,該事件指向notify方法
  • 子組件的notify方法在處理時(shí),調(diào)用了$dispatch,將事件派發(fā)到父組件的child-msg事件,并給該該事件提供了一個(gè)msg參數(shù)
  • 父組件的events選項(xiàng)中定義了child-msg事件,父組件接收到子組件的派發(fā)后,調(diào)用child-msg事件。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 本文章是我最近在公司的一場(chǎng)內(nèi)部分享的內(nèi)容。我有個(gè)習(xí)慣就是每次分享都會(huì)先將要分享的內(nèi)容寫成文章。所以這個(gè)文集也是用來(lái)...
    Awey閱讀 9,477評(píng)論 4 67
  • 什么是組件 組件(Component)是 Vue.js 最強(qiáng)大的功能之一。組件可以擴(kuò)展 HTML 元素,封裝可重用...
    angelwgh閱讀 790評(píng)論 0 0
  • 這篇筆記主要包含 Vue 2 不同于 Vue 1 或者特有的內(nèi)容,還有我對(duì)于 Vue 1.0 印象不深的內(nèi)容。關(guān)于...
    云之外閱讀 5,082評(píng)論 0 29
  • 前言 本文由閱讀一篇vue.js組件文章學(xué)習(xí)后筆記http://www.cnblogs.com/keepfool/...
    海娩閱讀 792評(píng)論 2 2
  • 1、在網(wǎng)站www.phpcms.cn下載安裝包。有GBK 和 UTF8兩個(gè)版本,推薦使用UTF8版本。2、在環(huán)境下...
    捔落纏綿閱讀 2,098評(píng)論 1 0