vue組件的詳細介紹

核心目標(biāo)

為了可重用性高昼激,減少重復(fù)性開發(fā),我們可以按照template抹恳、style员凝、script的拆分方式,放置到對應(yīng)的.vue文件中奋献。

組件概括

vue組件可以理解為預(yù)先定義好的ViewModel類健霹。一個組件可以預(yù)定義很多選項,最核心的有:
  1. 模板template:模板反映了數(shù)據(jù)和最終展現(xiàn)給用戶的DOM之間的映射關(guān)系瓶蚂,
  2. 初始數(shù)據(jù)data:一個組件的初始數(shù)據(jù)狀態(tài)糖埋,對于可重復(fù)的組件來說,通常是私有的狀態(tài)窃这。
  3. 接收的外部的參數(shù)(props):組件之間通過參數(shù)來進行數(shù)據(jù)的傳遞和共享瞳别,參數(shù)默認是單項綁定,但也可以顯示聲明為雙向綁定杭攻。
  4. 方法(methods):對數(shù)據(jù)的改動操作一般都在組件內(nèi)進行祟敛。可以通過v-on指令將用戶輸入事件和組件方法進行綁定兆解。
  5. 生命周期函數(shù)(鉤子函數(shù)):一個組件會觸發(fā)多個生命周期函數(shù)馆铁,在這些鉤子函數(shù)中可以封裝一些自定義邏輯』驹祝可以理解為controller的邏輯被分散到了這些鉤子函數(shù)中叼架。

注冊組件

注冊組件就是利用Vue.component()方法,先傳入一個自定義組件的名字衣撬,然后傳入這個組件的配置乖订。

(組件名不要帶有大寫字母,多個單詞使用中劃線my-dom)

  • 全局組件
    (直接使用Vue.component()創(chuàng)建的組件具练,所有的Vue實例都可以使用乍构。)
    (一般寫插件的時候全局組件使用多一些)
 Vue.component('mycomponent',{      //自定義組件名mycomponent
    template: `<div>這是一個自定義組件</div>`,
    data () {
      return {
        message: 'hello world'
      }
    }
  })
  • 局部注冊組件
    使用三部曲1.創(chuàng)建這個組件;2.注冊這個組件;3.使用這個組件哥遮;
<div id="app">
    <mycomponent></mycomponent>   //3.組件的使用
    <my-component></my-component>    //3.組件的使用
</div>
<script>
  //1.創(chuàng)建這個組件
  let  mycomponent={
      template: `<div>這是一個局部的自定義組件岂丘,只能在當(dāng)前Vue實例中使用{{aa}}</div>`,
      data(){
        return {'aa':'hello'}
      }
   };

  let  app = new Vue({
    el: '#app',
    data: {
    },
    components: {
      mycomponent,//2.注冊這個組件
      }
    }
  })
</script>
  • 模板的要求:組件的模板只能有一個根元素眠饮。
template: `<div>
                元素1.....
                元素2.....
                元素3.....
           </div>`,
  • 組件中的data必須是函數(shù)奥帘。
data:function(){
            return {'aaa':'bbb'}//template中可以使用aaa
        },
  • 組件的屬性props。
    Vue組件通過props屬性來聲明一個自己的屬性仪召,然后父組件就可以往里面?zhèn)鬟f數(shù)據(jù)寨蹋。
<div id="app1">
    動態(tài)操作屬性:name是變量(讀取實例中data的值)
    <hello :n="name"></hello>
</div>
<div id="app2">
    靜態(tài)的屬性:name是常量(就是name)
    <hello n="name"></hello>
</div>
<script>
    Vue.component('hello',{
        props:['n'],//通過父組件傳過來的數(shù)據(jù) name變量
        data:function(){
            return {'aaa':'bbb'}
        },
        template:'<p>{{aaa}} {{n}}</p>'
    })
    var app1=new Vue({
        el:'#app1',
        data:{
            name:'haha'
        }
    })
    var app2=new Vue({
        el:'#app2',
        data:{
            name:'haha'
        }
    })
</script>

渲染結(jié)果


props.png
  • props的驗證。

組件之間的通信

子組件給父組件傳遞數(shù)據(jù)扔茅,利用事件的訂閱發(fā)布模式
  • 1.給子組件的template上的元素綁定事件(如click)已旧,執(zhí)行子組件的方法(如changeData),子組件的方法中發(fā)射一個事件(如s)召娜,傳一個數(shù)據(jù)(如lalala)运褪;
  • 2.父組件中,定義一個方法(如getData)用來拿到子組件的數(shù)據(jù)玖瘸。
  • 3.在自定義的組件上綁定子組件傳過去的事件(s)秸讹,執(zhí)行事件(s)執(zhí)行的是getData函數(shù),getData函數(shù)中拿到數(shù)據(jù)(data店读,就是子組件傳過去的lalala)嗦枢。
<div id="app">
    <parent></parent>
</div>
<template id="parent">
    <div>
        <p>父組件{{msg}}</p>//點擊子組件觸發(fā)getData獲取到子組件轉(zhuǎn)來的msg數(shù)據(jù)攀芯,綁定到父組件上
        <children @s="getData"></children>
    </div>
</template>
<script>
    var app=new Vue({
        el:'#app',
        components:{
            parent:{
                template:'#parent',
                data(){
                    return {msg:'aaa'};
                },
                methods:{
                    getData(data){
                        alert(data);//子組件傳過來的數(shù)據(jù)
                        this.msg=data;
                    }
                },
                components:{
                    children:{
                        template:'<p @click="changeData">子組件</p>',
                        methods:{
                            changeData(){
                                this.$emit('s','lalala');//傳遞給父組件
                            }
                        }
                    }
                }
            }
        }
    })
</script>
父組件給子組件傳遞數(shù)據(jù)(利用props屬性)
<div id="app">
    <parent></parent>
</div>

<script>
    var app=new Vue({
        el:'#app',
        components:{//一個父組件里邊可以包含多個子組件
            parent:{
                template:'<h1 >{{msg}},父組件<children :n="msg"></children></h1>',
                data:function(){//父組件的數(shù)據(jù) 傳給子組件
                    return {msg:'hello'}
                },
                components:{
                  children:{
                      props:['n'],//根據(jù)props拿到父組件中寫的動態(tài)屬性拿到數(shù)據(jù)
                      template:'<h2>{{n}},子組件</h2>',
                  }
                }
            }
        }
    })
兄弟組件之間傳遞數(shù)據(jù) (事件車---原理也是事件的訂閱發(fā)布模式)
注意:
  • 每一個vue的實例都是獨立的屯断;相互之間不能直接進行改變數(shù)據(jù);
  • 給兩個不同的組件找一個載體侣诺;把共同的方法放在這個載體上殖演;
  • 這個載體就是 let eventBus = new Vue; // 創(chuàng)建一個新的vue實例;
  • 在這個新的實例上年鸳,有 $on: 訂閱 $emit: 發(fā)布;
  • $on的綁定要基于鉤子函數(shù)趴久,一般放在created或者mounted上
<div id="app">
    <tmp1></tmp1>
    <tmp2></tmp2>
</div>

<script>
    var eventBus=new Vue();
    var app = new Vue({
        el: '#app',
        data: {},
        components: {
            tmp1: {
                template: "<h1>組件1{{msg}}</h1>",
                data(){
                    return {msg:""}
                },
                mounted(){//鉤子函數(shù),頁面一加載進來的時候就已經(jīng)綁定好了
                   eventBus.$on('aaa',(data)=>{
                        this.msg=data;
                    })
                }
            },
            tmp2: {
                template: "<h1 @click='sendData'>組件2{{msg}}</h1>",
                data(){
                    return {msg: 'hello'}
                },
                methods:{
                    sendData(){
                        //發(fā)布數(shù)據(jù)
                        eventBus.$emit('aaa',this.msg)
                    }
                }
            }
        }
    })
</script>

數(shù)據(jù)同步(子組件的數(shù)據(jù)和父組件保持一致)

數(shù)據(jù)同步的核心:父組件給子組件傳遞“引用數(shù)據(jù)類型的數(shù)據(jù)”搔确;
<div id="app">
<parent></parent>
</div>
<template id="parent">
<div>
    <h1>父組件 <mark>{{msg.name}}</mark></h1>
    <children :n="msg"></children>
</div>
</template>
<template id="children">
    <h2 @click="changeData">子組件 {{n.name}}</h2>
</template>
<script>
    //數(shù)據(jù)同步的核心:父組件給子組件傳遞“引用數(shù)據(jù)類型的數(shù)據(jù)”彼棍;
    var app=new Vue({
        el:'#app',
        components:{
            parent:{
                template:'#parent',
                data(){
                    return {msg:{name:'hahha'}}
                },
                components:{
                    children:{
                        props:['n'],
                        template:'#children',
                        methods:{
                            changeData(){
                                this.n.name='lallala'
                            },
                        }
                    }

                }
            }
        }
    })
</script>
數(shù)據(jù)不同步(不直接使用父組件傳的值,用data屬性再自己的組件內(nèi)做一個中間變量膳算,防止報錯)
<parent></parent>
</div>
<template id="parent">
<div>
    <h1>父組件 <mark>{{msg}}</mark></h1>
    <children :n="msg"></children>
</div>
</template>
<script>
    //數(shù)據(jù)不同步的核心:中間變量接收避免報錯座硕;
    var app=new Vue({
        el:'#app',
        components:{
            parent:{
                template:'#parent',
                data(){
                    return {msg:'hahha'}
                },
                components:{
                    children:{
                        props:['n'],
                        template:'<h2 @click="changeData">子組件 {}</h2>',
                        data(){
                            return {b:this.n}
                        },
                        methods:{
                            changeData(){
                                this.b='lallala'
                            },
                        }
                    }
                }
            }
        }
    })
</script>

組件切換

js動態(tài)控制template(也可以用is屬性控制)
<div id="app">
    <div class="container">
        <div @click="comp='zujian1'">顯示組件1</div>
        <div @click="comp='zujian2'">顯示組件2</div>
    </div>
    <!--aaa標(biāo)簽是核心涕蜂,必須得寫华匾,通過is決定顯示那個組件-->
    <aaa :is="comp"></aaa>
</div>

<script>
    var app=new Vue({
        el:'#app',
        data:{
            comp:'zujian2',
        },
        components:{
            zujian1:{
                template:'<h1>組件1</h1>'
            },
            zujian2:{
                template:'<h1>組件2</h1>'
            }
        }
    })
</script>

插槽(slot官網(wǎng)有詳細介紹)

slot相當(dāng)于子組件設(shè)置了一個地方,如果在調(diào)用它的時候机隙,往它的開閉標(biāo)簽之間放了東西蜘拉,那么它就把這些東西放到slot中萨西。
  1. 當(dāng)子組件中沒有slot時,父組件放在子組件標(biāo)簽內(nèi)的東西將被丟棄旭旭;
  2. 子組件的slot標(biāo)簽內(nèi)可以放置內(nèi)容谎脯,當(dāng)父組件沒有放置內(nèi)容在子組件標(biāo)簽內(nèi)時,slot中的內(nèi)容會渲染出來持寄;
  3. 當(dāng)父組件在子組件標(biāo)簽內(nèi)放置了內(nèi)容時穿肄,slot中的內(nèi)容被丟棄
    實例:
<div id="app">
    <hello>//使用組件
        lalalala
        <!--給插槽起好名字-->
        <div slot="div1">1111111111111</div>
        <div slot="div2">2222222222222</div>
    </hello>
</div>
<template id="temp1">//模板
    <h1>
        hello
        <!--無名插槽-->
        <slot></slot>
        <!--有名插槽 可以根據(jù)插槽切換順序-->
        <slot name="div2"></slot>
        <slot name="div1"></slot>
    </h1>
</template>
<script>
    var app=new Vue({
        el:'#app',
        data:{

        },
        components:{
            hello:{
                template:"#temp1"
            }
        }
    })

組件文件示例

父組件.vue

<template>
    <div class="">
        <div class="home-container">
            <Banner></Banner>
            <quick-link :allAmount="allAmount"> </quick-link>
            <Recommended></Recommended>
        </div>
       <m-footer></m-footer>
    </div>
</template>

<script>
    import axios from 'axios'
    import MFooter from '../footer.vue'
    import Banner from './banner.vue'
    import QuickLink from './quickLink.vue'
    import Recommended from './recommended.vue'
    import {setSession} from '../../common/userCenter'
    import {loadAppHomeAct,loadStatisticalData} from '../../api/api'
    export default {
        data(){
            return{
                allAmount:[]
            }
        },
        components:{
            MFooter,
            Banner,
            QuickLink,
            Recommended
        },
        created(){
            this.fetchCookies();
        },
        methods:{
           getQueryString: function (name) {
                var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
                var url=decodeURIComponent(window.location.search);
                var r = url.substr(1).match(reg);
                if (r != null) return (r[2]);
                return "";
            }
        }
    }
</script>

<style>
    @import "home.css";
</style>

鏈接到路由配置

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市际看,隨后出現(xiàn)的幾起案子咸产,更是在濱河造成了極大的恐慌,老刑警劉巖仲闽,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件脑溢,死亡現(xiàn)場離奇詭異,居然都是意外死亡赖欣,警方通過查閱死者的電腦和手機屑彻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來顶吮,“玉大人社牲,你說我怎么就攤上這事°擦耍” “怎么了搏恤?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長湃交。 經(jīng)常有香客問我熟空,道長,這世上最難降的妖魔是什么搞莺? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任息罗,我火速辦了婚禮,結(jié)果婚禮上才沧,老公的妹妹穿的比我還像新娘迈喉。我一直安慰自己,他們只是感情好温圆,可當(dāng)我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布挨摸。 她就那樣靜靜地躺著,像睡著了一般捌木。 火紅的嫁衣襯著肌膚如雪油坝。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天,我揣著相機與錄音澈圈,去河邊找鬼彬檀。 笑死,一個胖子當(dāng)著我的面吹牛瞬女,可吹牛的內(nèi)容都是我干的窍帝。 我是一名探鬼主播,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼诽偷,長吁一口氣:“原來是場噩夢啊……” “哼坤学!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起报慕,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤深浮,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后眠冈,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體飞苇,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年蜗顽,在試婚紗的時候發(fā)現(xiàn)自己被綠了布卡。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡雇盖,死狀恐怖忿等,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情崔挖,我是刑警寧澤贸街,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站虚汛,受9級特大地震影響匾浪,放射性物質(zhì)發(fā)生泄漏皇帮。R本人自食惡果不足惜卷哩,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望属拾。 院中可真熱鬧将谊,春花似錦、人聲如沸渐白。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽纯衍。三九已至栋齿,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背瓦堵。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工基协, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人菇用。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓澜驮,卻偏偏與公主長得像,于是被迫代替她去往敵國和親惋鸥。 傳聞我的和親對象是個殘疾皇子杂穷,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,086評論 2 355

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