第3章 vue組件開發(fā)

1. 組件開發(fā)

在vue中,組件是最重要的組合部分,官方中定義組件為可復(fù)用的vue實(shí)例,分為全局組件和局部組件。

1.1 全局組件

使用全局組件的步驟如下:

  • 調(diào)用vue.extend()創(chuàng)建一個(gè)組件構(gòu)造器,該構(gòu)造器中有一個(gè)選項(xiàng)對(duì)象的template屬性可以用來定義組件要渲染的HTML
  • 使用vue.component()注冊(cè)組件,需要提供2個(gè)參數(shù):組件的標(biāo)簽和組件構(gòu)造器。vue.component()內(nèi)部會(huì)調(diào)用組件構(gòu)造器,創(chuàng)建一個(gè)組件實(shí)例
  • 將組建掛載到某個(gè)vue實(shí)例下

因?yàn)榻M件是可復(fù)用的vue實(shí)例,所以它們也能接收data、computed、watch、methods以及生命周期鉤子等選項(xiàng)

<div id="demo">
    <haha></haha>
</div>
<script type="text/javascript">
    var red = Vue.extend({
        template: "<span style='color: red;'>全局組件</span>"
    });
    Vue.component('haha',red);
    var demo = new Vue({
        el: "#demo"
    })
</script>

1.2 局部組件

調(diào)用Vue.component()注冊(cè)組件時(shí),組件的注冊(cè)是全局的,這意味著該組件可以在任意Vue示例下使用。 如果不需要全局注冊(cè),或者是讓組件使用在其它組件內(nèi),可以用選項(xiàng)對(duì)象的components屬性實(shí)現(xiàn)局部注冊(cè)。

<div id="demo">
    <haha></haha>
</div>
<script type="text/javascript">
    var red = Vue.extend({
        template: "<span style='color: red;'>局部組件</span>"
    });
    var demo = new Vue({
        el: "#demo",
        components:{
            haha:red
        }
    })
</script>

雖然上面的組件是在某個(gè)具體的vue實(shí)例下注冊(cè)的,但是組件構(gòu)造器還是全局的,這個(gè)并不是完全意義上的局部組件,下面這種組件才是真正意義上的局部組件。

<div id="demo">
    <haha></haha>
</div>
<script type="text/javascript">
    var demo = new Vue({
        el: "#demo",
        components:{
            haha:{
                template:'<span style="color: red;">局部組件</span>'
            }
        }
    })
</script>

1.3 組件模板

可以通過<template>標(biāo)記聲明組件,再通過全局或局部注冊(cè)組件來使用。
組件中data不是屬性,是方法,需要將數(shù)據(jù)通過返回值進(jìn)行返回

<div id="demo">
    <haha></haha>
</div>
<template id="abc">
    <div @click="test1" style="cursor: pointer;">{{message}}</div>
</template>
<script type="text/javascript">
    var demo = new Vue({
        el: "#demo",
        components:{
            haha:{
                data(){
                    return {
                        message: 'init info'
                    }
                },
                methods:{
                    test1(){
                        if(this.message == 'init info'){
                            this.message = 'click info'
                        }else{
                            this.message = 'init info'
                        }   
                    }
                },
                template:"#abc"
            }
        }
    })
</script>

2. 組件通信

2.1 父子組件

當(dāng)繼續(xù)在組件中寫組件,形成組件嵌套的時(shí)候,就是所謂的父子組件。

<div id="demo">
    <haha></haha>
</div>

<template id="haha">
    <div>
        <h2>{{message}}</h2>
        <xixi></xixi>
    </div>
</template>

<template id="xixi">
    <div>
        <h3>{{info}}</h3>
    </div>
</template>

<script type="text/javascript">
    var demo = new Vue({
        el: "#demo",
        components:{
            haha:{
                data(){
                    return {
                        message: '父組件'
                    }
                },
                template:"#haha",
                components:{
                    xixi:{
                        data(){
                            return {
                                info:'子組件'
                            }
                        },
                        template: "#xixi"
                    }
                    
                }
            }
        }
    })
</script>

2.2 子組件獲取父組件的數(shù)據(jù)

在vue中,組件實(shí)例的作用域是孤立的,默認(rèn)情況下,父子組件的數(shù)據(jù)是不能共享的,也就是說,子組件是不能直接訪問父組件的數(shù)據(jù)的。為此,vue給我們提供了一個(gè)數(shù)據(jù)傳遞的選項(xiàng)prop,用來將父組件的數(shù)據(jù)傳遞給子組件。

  1. 父組件template中,調(diào)用子組件位置通過:msg="message"表示將父組件中的data:message傳遞給子組件,名字為msg
  2. 子組件components中通過props聲明['msg']表示接收父組件推送的數(shù)據(jù),子組件template直接{{msg}}進(jìn)行調(diào)用
<div id="demo">
    <haha></haha>
</div>

<template id="haha">
    <div>
        <h2>{{message}}</h2>
        <xixi :msg="message"></xixi>
    </div>
</template>

<template id="xixi">
    <div>
        <h3>{{info}} -> {{msg}}</h3>
    </div>
</template>

<script type="text/javascript">
    var demo = new Vue({
        el: "#demo",
        components:{
            haha:{
                data(){
                    return {
                        message: '父組件'
                    }
                },
                template:"#haha",
                components:{
                    xixi:{
                        data(){
                            return {
                                info:'子組件'
                            }
                        },
                        props:['msg'],
                        template: "#xixi"
                    }
                    
                }
            }
        }
    })
</script>

2.3 父組件獲取子組件的數(shù)據(jù)

父組件獲取子組件需要子組件事件驅(qū)動(dòng),通過觸發(fā)一個(gè)事件將自身的數(shù)據(jù)發(fā)送給父組件。
步驟:
1.在子組件的methods中編寫send方法,其中通過emit函數(shù)將需要傳遞的數(shù)據(jù)綁定一個(gè)名字“child-msg”
2.在父組件的template中調(diào)用子組件的標(biāo)記處,通過@child-msg指向父組件的綁定函數(shù)"getMsg"
3.在父組件的methods中編寫getMsg函數(shù),通過方法參數(shù)接收傳遞過來的數(shù)據(jù),并將其賦值給某個(gè)data(cmsg)
4.通過使用cmsg來使用子組件的數(shù)據(jù)。

<div id="demo">
    <haha></haha>
</div>

<template id="haha">
    <div>
        <h2>{{message}}</h2>
        <xixi :msg="message" @child-msg="getMsg"></xixi>
        <div>{{cmsg}}</div>
    </div>
</template>

<template id="xixi">
    <div @click="send">
        <h3>{{info}} -> {{msg}}</h3>
    </div>
</template>

<script type="text/javascript">
    var demo = new Vue({
        el: "#demo",
        components:{
            haha:{
                data(){
                    return {
                        message: '父組件',
                        cmsg:''
                    }
                },
                methods:{
                    getMsg(msg){
                        this.cmsg = msg;
                    }
                },
                template:"#haha",
                components:{
                    xixi:{
                        data(){
                            return {
                                info:'子組件數(shù)據(jù)'
                            }
                        },
                        props:['msg'],
                        template: "#xixi",
                        methods:{
                            send(){
                                this.$emit('child-msg',this.info);
                            }
                        }
                    }
                    
                }
            }
        }
    })
</script>

需要強(qiáng)調(diào)的是,父子組件數(shù)據(jù)時(shí)單向更新的

  • 當(dāng)父組件數(shù)據(jù)變化時(shí),子組件中的顯示會(huì)實(shí)時(shí)更新。
  • 當(dāng)子組件數(shù)據(jù)變化時(shí),需要觸發(fā)事件來驅(qū)動(dòng)父組件數(shù)據(jù)更新。

2.4 $children和$ref

當(dāng)一個(gè)父組件中存在多個(gè)子組件時(shí),可以通過$children來訪問其下所有子組件,它會(huì)返回一個(gè)包含所有子組件的數(shù)組

<div id="count">
    <button @click="showmsg">
      顯示兩個(gè)組件的信息
    </button>
    <child1></child1>
    <child2></child2>
    </div>
<template id="child1">
  <div>
    {{ msg }}
  </div>
</template>
<template id="child2">
  <div>
    {{ msg }}
  </div>
</template>
<script>
    Vue.component('child1', {
      template: '#child1',
      data () {
        return {
          msg: '這是子組件1的信息'
        }
      }
    })
    Vue.component('child2', {
      template: '#child2',
      data () {
        return {
          msg: '這是子組件2的信息'
        }
      }
    })
    new Vue({
      el: '#count',
      data: {

      },
      methods: {
        showmsg () {
            for(var i = 0; i < this.$children.length; i++) {
            alert(this.$children[i].msg)
          }
        }
      }
    })
</script>

有時(shí)候組件過多的話,就很記清各個(gè)組件的順序與位置,所以通過給子組件一個(gè)索引ID來進(jìn)行快速定位

<div id="count">
    <button @click="showmsg">
      顯示兩個(gè)組件的信息
    </button>
   <child1 ref='c1'></child1>
    <child2 ref='c2'></child2>
    </div>
<template id="child1">
  <div>
    {{ msg }}
  </div>
</template>
<template id="child2">
  <div>
    {{ msg }}
  </div>
</template>
<script>
    Vue.component('child1', {
      template: '#child1',
      data () {
        return {
          msg: '這是子組件1的信息'
        }
      }
    })
    Vue.component('child2', {
      template: '#child2',
      data () {
        return {
          msg: '這是子組件2的信息'
        }
      }
    })
    new Vue({
      el: '#count',
      data: {

      },
      methods: {
        showmsg () {
            alert(this.$refs.c1.msg)
          alert(this.$refs.c2.msg)
        }
      }
    })
</script>

2.5 $parent和$root

子組件通過訪問$parent獲得其父組件的實(shí)例對(duì)象

<div id="count">
    父組件中的msg: {{ msg }}
    <child1 ref='c1'></child1>
    <child2 ref='c2'></child2>
</div>
<template id="child1">
  <div>
    {{ msg }}
    <button @click="showpmsg">
      顯示父組件msg
    </button>
  </div>
</template>
<template id="child2">
  <div>
    {{ msg }}
  </div>
</template>
<script>
    Vue.component('child1', {
      template: '#child1',
      data () {
        return {
          msg: '這是子組件1的信息'
        }
      },
      methods: {
        showpmsg () {
                alert(this.$parent.msg)
        }
      }
    })
    Vue.component('child2', {
      template: '#child2',
      data () {
        return {
          msg: '這是子組件2的信息'
        }
      }
    })
    new Vue({
      el: '#count',
      data: {
        msg: 'hello parent'
      }
    })
</script>

子組件訪問根組件 $root 當(dāng)前組件樹的根 Vue 實(shí)例。如果當(dāng)前實(shí)例沒有父實(shí)例,此實(shí)例將會(huì)是其自已。

<div id="count">
    父組件中的msg: {{ msg }}
        <child1 ref='c1'></child1>
    <child2 ref='c2'></child2>
    </div>
<template id="child1">
  <div>
    {{ msg }}
    <cchild></cchild>
  </div>
</template>
<template id="child2">
  <div>
    {{ msg }}
  </div>
</template>
<template id="cchild">
  <div>
    <button @click="showroot">
      showrootmsg
    </button>
  </div>
</template>
<script>
    Vue.component('child1', {
      template: '#child1',
      data () {
        return {
          msg: '這是子組件1的信息'
        }
      },
      methods: {
        showpmsg () {
                alert(this.$parent.msg)
        }
      }
    })
    Vue.component('child2', {
      template: '#child2',
      data () {
        return {
          msg: '這是子組件2的信息'
        }
      }
    })
    Vue.component('cchild', {
      template: '#cchild',
      data () {
        return {
          msg: '這是子組件1的信息'
        }
      },
      methods: {
        showroot () {
                alert(this.$root.msg)
        }
      }
    })
    new Vue({
      el: '#count',
      data: {
        msg: 'hello root'
      }
    })
</script>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Vue 實(shí)例 屬性和方法 每個(gè) Vue 實(shí)例都會(huì)代理其 data 對(duì)象里所有的屬性:var data = { a:...
    云之外閱讀 2,373評(píng)論 0 6
  • 組件簡(jiǎn)介 組件系統(tǒng)是Vue.js其中一個(gè)重要的概念,它提供了一種抽象,讓我們可以使用獨(dú)立可復(fù)用的小組件來構(gòu)建大型應(yīng)...
    前端一菜鳥閱讀 942評(píng)論 0 16
  • 第一章 Vue概述 what? Vue是實(shí)現(xiàn)UI層的漸進(jìn)式j(luò)s框架,核心庫(kù)關(guān)注視圖層,簡(jiǎn)單的ui構(gòu)建,復(fù)雜的路由控...
    fastwe閱讀 833評(píng)論 0 0
  • 什么是組件? 組件 (Component) 是 Vue.js 最強(qiáng)大的功能之一。組件可以擴(kuò)展 HTML 元素,封裝...
    youins閱讀 9,708評(píng)論 0 13
  • 本文章是我最近在公司的一場(chǎng)內(nèi)部分享的內(nèi)容。我有個(gè)習(xí)慣就是每次分享都會(huì)先將要分享的內(nèi)容寫成文章。所以這個(gè)文集也是用來...
    Awey閱讀 9,577評(píng)論 4 67

友情鏈接更多精彩內(nèi)容