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

1. 組件開發(fā)

在vue中蚌讼,組件是最重要的組合部分芯义,官方中定義組件為可復用的vue實例趁舀,分為全局組件和局部組件嵌洼。

1.1 全局組件

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

  • 調用vue.extend()創(chuàng)建一個組件構造器案疲,該構造器中有一個選項對象的template屬性可以用來定義組件要渲染的HTML
  • 使用vue.component()注冊組件,需要提供2個參數(shù):組件的標簽和組件構造器咱台。vue.component()內部會調用組件構造器络拌,創(chuàng)建一個組件實例
  • 將組建掛載到某個vue實例下

因為組件是可復用的vue實例,所以它們也能接收data回溺、computed春贸、watch、methods以及生命周期鉤子等選項

<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 局部組件

調用Vue.component()注冊組件時遗遵,組件的注冊是全局的萍恕,這意味著該組件可以在任意Vue示例下使用。 如果不需要全局注冊车要,或者是讓組件使用在其它組件內允粤,可以用選項對象的components屬性實現(xiàn)局部注冊。

<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>

雖然上面的組件是在某個具體的vue實例下注冊的翼岁,但是組件構造器還是全局的类垫,這個并不是完全意義上的局部組件,下面這種組件才是真正意義上的局部組件琅坡。

<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>標記聲明組件悉患,再通過全局或局部注冊組件來使用。
組件中data不是屬性榆俺,是方法售躁,需要將數(shù)據(jù)通過返回值進行返回

<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 父子組件

當繼續(xù)在組件中寫組件坞淮,形成組件嵌套的時候,就是所謂的父子組件陪捷。

<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ù)據(jù)是不能共享的啡直,也就是說,子組件是不能直接訪問父組件的數(shù)據(jù)的凌盯。為此付枫,vue給我們提供了一個數(shù)據(jù)傳遞的選項prop,用來將父組件的數(shù)據(jù)傳遞給子組件驰怎。

  1. 父組件template中阐滩,調用子組件位置通過:msg="message"表示將父組件中的data:message傳遞給子組件,名字為msg
  2. 子組件components中通過props聲明['msg']表示接收父組件推送的數(shù)據(jù)县忌,子組件template直接{{msg}}進行調用
<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ù)

父組件獲取子組件需要子組件事件驅動掂榔,通過觸發(fā)一個事件將自身的數(shù)據(jù)發(fā)送給父組件。
步驟:
1.在子組件的methods中編寫send方法症杏,其中通過emit函數(shù)將需要傳遞的數(shù)據(jù)綁定一個名字“child-msg”
2.在父組件的template中調用子組件的標記處装获,通過@child-msg指向父組件的綁定函數(shù)"getMsg"
3.在父組件的methods中編寫getMsg函數(shù),通過方法參數(shù)接收傳遞過來的數(shù)據(jù)厉颤,并將其賦值給某個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>

需要強調的是,父子組件數(shù)據(jù)時單向更新的

  • 當父組件數(shù)據(jù)變化時逼友,子組件中的顯示會實時更新精肃。
  • 當子組件數(shù)據(jù)變化時,需要觸發(fā)事件來驅動父組件數(shù)據(jù)更新帜乞。

2.4 $children和$ref

當一個父組件中存在多個子組件時司抱,可以通過$children來訪問其下所有子組件,它會返回一個包含所有子組件的數(shù)組

<div id="count">
    <button @click="showmsg">
      顯示兩個組件的信息
    </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>

有時候組件過多的話黎烈,就很記清各個組件的順序與位置习柠,所以通過給子組件一個索引ID來進行快速定位

<div id="count">
    <button @click="showmsg">
      顯示兩個組件的信息
    </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獲得其父組件的實例對象

<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 當前組件樹的根 Vue 實例。如果當前實例沒有父實例照棋,此實例將會是其自已资溃。

<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>
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市烈炭,隨后出現(xiàn)的幾起案子溶锭,更是在濱河造成了極大的恐慌,老刑警劉巖梳庆,帶你破解...
    沈念sama閱讀 212,332評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件暖途,死亡現(xiàn)場離奇詭異,居然都是意外死亡膏执,警方通過查閱死者的電腦和手機驻售,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,508評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來更米,“玉大人欺栗,你說我怎么就攤上這事≌髀停” “怎么了迟几?”我有些...
    開封第一講書人閱讀 157,812評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長栏笆。 經(jīng)常有香客問我类腮,道長,這世上最難降的妖魔是什么蛉加? 我笑而不...
    開封第一講書人閱讀 56,607評論 1 284
  • 正文 為了忘掉前任蚜枢,我火速辦了婚禮,結果婚禮上针饥,老公的妹妹穿的比我還像新娘厂抽。我一直安慰自己,他們只是感情好丁眼,可當我...
    茶點故事閱讀 65,728評論 6 386
  • 文/花漫 我一把揭開白布筷凤。 她就那樣靜靜地躺著,像睡著了一般苞七。 火紅的嫁衣襯著肌膚如雪藐守。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,919評論 1 290
  • 那天莽鸭,我揣著相機與錄音吗伤,去河邊找鬼。 笑死硫眨,一個胖子當著我的面吹牛足淆,可吹牛的內容都是我干的。 我是一名探鬼主播礁阁,決...
    沈念sama閱讀 39,071評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼巧号,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了姥闭?” 一聲冷哼從身側響起丹鸿,我...
    開封第一講書人閱讀 37,802評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎棚品,沒想到半個月后靠欢,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體廊敌,經(jīng)...
    沈念sama閱讀 44,256評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,576評論 2 327
  • 正文 我和宋清朗相戀三年门怪,在試婚紗的時候發(fā)現(xiàn)自己被綠了骡澈。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,712評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡掷空,死狀恐怖肋殴,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情坦弟,我是刑警寧澤护锤,帶...
    沈念sama閱讀 34,389評論 4 332
  • 正文 年R本政府宣布,位于F島的核電站酿傍,受9級特大地震影響烙懦,放射性物質發(fā)生泄漏。R本人自食惡果不足惜赤炒,卻給世界環(huán)境...
    茶點故事閱讀 40,032評論 3 316
  • 文/蒙蒙 一修陡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧可霎,春花似錦魄鸦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至旷余,卻和暖如春绢记,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背正卧。 一陣腳步聲響...
    開封第一講書人閱讀 32,026評論 1 266
  • 我被黑心中介騙來泰國打工蠢熄, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人炉旷。 一個月前我還...
    沈念sama閱讀 46,473評論 2 360
  • 正文 我出身青樓签孔,卻偏偏與公主長得像,于是被迫代替她去往敵國和親窘行。 傳聞我的和親對象是個殘疾皇子饥追,可洞房花燭夜當晚...
    茶點故事閱讀 43,606評論 2 350

推薦閱讀更多精彩內容

  • Vue 實例 屬性和方法 每個 Vue 實例都會代理其 data 對象里所有的屬性:var data = { a:...
    云之外閱讀 2,204評論 0 6
  • 組件簡介 組件系統(tǒng)是Vue.js其中一個重要的概念,它提供了一種抽象罐盔,讓我們可以使用獨立可復用的小組件來構建大型應...
    前端一菜鳥閱讀 853評論 0 16
  • 第一章 Vue概述 what? Vue是實現(xiàn)UI層的漸進式js框架但绕,核心庫關注視圖層,簡單的ui構建,復雜的路由控...
    fastwe閱讀 710評論 0 0
  • 什么是組件捏顺? 組件 (Component) 是 Vue.js 最強大的功能之一六孵。組件可以擴展 HTML 元素,封裝...
    youins閱讀 9,465評論 0 13
  • 本文章是我最近在公司的一場內部分享的內容幅骄。我有個習慣就是每次分享都會先將要分享的內容寫成文章狸臣。所以這個文集也是用來...
    Awey閱讀 9,433評論 4 67