Vue中最重要的角色組件詳解

可復(fù)用性的組件詳解

使用組件的原因

作用:提高代碼的復(fù)用性

組件的使用方法

  • 全局注冊
<div id="app">
        <my-componet></my-componet>
    </div>
    <!-- 對應(yīng)的內(nèi)容<div id="app"><div>我是一個(gè)全局組件</div></div> -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    <script>
        // Vue.component(tag, {
        //     template: '<div></div>'
        // })
        // 注冊組件 第一個(gè)參數(shù) 標(biāo)簽名 第二個(gè)是要渲染的魔板
        Vue.component('my-componet', {
            template: '<div>我是一個(gè)全局組件</div>'
        })
        var app = new Vue({
            el: '#app',
            data: {

            }
        })
    </script>
  • 優(yōu)點(diǎn):所有的Vue實(shí)例都可以用
  • 缺點(diǎn):權(quán)限太大坪圾,容錯(cuò)率降低
  • 局部注冊
<div id="app" style="border:2px solid red ">
        <!-- 全局組件 -->
        <my-componet></my-componet>
        <!-- 局部組件  -->
        <app-componet></app-componet>
    </div>
    <!-- 對照試驗(yàn) 全局組件和局部組件 -->
    <div id="bpp" style="border:2px solid green;margin-top:5px; ">
        <!-- 全局組件 -->
        <my-componet></my-componet>
        <!-- app局部組件    只能在所注冊的實(shí)例中使用   這里不會(huì)顯示 -->
        <app-componet></app-componet>
    </div>
    <!-- 對應(yīng)的內(nèi)容<div id="app"><div>我是一個(gè)全局組件</div></div> -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    <script>
        // Vue.component(tag, {
        //     template: '<div></div>'
        // })
        // 注冊全局組件 第一個(gè)參數(shù) 標(biāo)簽名 第二個(gè)是要渲染的魔板
        Vue.component('my-componet', {
            template: '<div>我是一個(gè)全局組件</div>'
        })
        var app = new Vue({
            el: '#app',
            // 局部組件 
            components: {
                'app-componet': {
                    template: '<div>我是app局部注冊的一個(gè)組件組件</div>'
                }
            },
            data: {

            }

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

            }
        })
    </script>
  • 注意
    vue組件的模板在某些情況下會(huì)受到html標(biāo)簽的限制,比如 <table>中只能還
    <tr> , <td>這些元素异雁,所以直接在table中使用組件是無效的,此時(shí)可以使用is屬性來掛載組件
<table>
     <tbody is="my-component"></tbody>
</table>

組件使用的小技巧

    1. 推薦使用小寫字母加-進(jìn)行命名(必須) child, my-componnet命名組件
    1. template中的內(nèi)容必須被一個(gè)DOM元素包括 框咙,也可以嵌套
    1. 在組件的定義中跟畅,除了template之外的其他選項(xiàng)—data,computed,methods
    1. data必須是一個(gè)方法data:function(){}
      小實(shí)踐:
<div id="app">
        <!-- 推薦使用小寫字母加-進(jìn)行命名(必須) -->
        <my-component></my-component>
        <!-- 點(diǎn)擊任何一個(gè) 都會(huì)執(zhí)行 可用組件方式解決  -->
        <button @click="plus">{{count}}</button>
        <button @click="plus">{{count}}</button>

        <hr><br>
        <!-- 組件方式解決 及 data必須是一個(gè)方法實(shí)踐  兩次點(diǎn)擊的按鈕 對象是不一致的 -->
        <btn-component></btn-component>
        <btn-component></btn-component>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                count: 1
            },
               //組件 
            components: {
                'my-component': {
                    // `template`中的內(nèi)容必須被一個(gè)`DOM元`素包括 ,也可以嵌套
                    template: '<div><span>組件小技巧</span></div>'
                },

                'btn-component': {
                    template: '<button @click="count++">{{count}}</button>',
                    // 組件中的data`必須是一個(gè)方法
                    data: function() {
                        return {
                            count: 0
                        }
                    }
                }
            },
            methods: {
                plus: function() {
                    return this.count++
                }
            }

        })
    </script>

使用props傳遞數(shù)據(jù) 父親向兒子傳遞數(shù)據(jù)

  1. 在組件中使用props來從父親組件接收參數(shù)堕扶,注意,在props中定義的屬性梭依,都可以在組件中直接使用
    2. propps來自父級稍算,而組件中data return的數(shù)據(jù)就是組件自己的數(shù)據(jù),兩種情況作用域就是組件本身役拴,可以在template糊探,computed,methods中直接使用
  2. props的值有兩種河闰,一種是字符串?dāng)?shù)組科平,一種是對象,本節(jié)先只講數(shù)組
  3. 可以使用v--bind動(dòng)態(tài)綁定父組件來的內(nèi)容
    先看個(gè)小栗子:

 在父組件里向子組件傳遞消息:
    <div id="app" style="border:2px solid green;height:200px;">
        <h5 style="text-align:center">我是父組件</h5>
        <child-component msg="我是來自父組件的內(nèi)容"></child-component>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    <script>
        // 一個(gè)父組件 
        var app = new Vue({
            el: '#app',
            // 定義一個(gè)子組件
            components: {
                'child-component': {
                    // 在組件中使用props來從父親組件接收參數(shù)姜性,
                    props: ['msg'],
                    // 注意瞪慧,在props中定義的屬性,都可以在 組件中直接使用
                    template: '<div style="border:2px solid red;height:70px;">{{msg}}</div>'
                }
            },
        })
    </script>

可以使用v--bind動(dòng)態(tài)綁定父組件來的內(nèi)容:小栗子

 在父組件里向子組件傳遞消息:
    <div id="app" style="border:2px solid green;height:400px;">
        <h5 style="text-align:center">我是父組件</h5>
        <child-component msg="我是來自父組件的內(nèi)容"></child-component>
        <br>
        <hr>使用v-bind進(jìn)行數(shù)據(jù)動(dòng)態(tài)綁定 把input中的msg傳遞給子組件
        <input type="text" v-model="parentmsg">
        <bind-component :msg="parentmsg"></bind-component>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    <script>
        // 一個(gè)父組件 
        var app = new Vue({
            el: '#app',
           //父組件定義的內(nèi)容
            data: {
                parentmsg: '今晚的月亮真圓啊'
            },
            // 定義一個(gè)子組件
            components: {
                'child-component': {
                    // 在組件中使用props來從父親組件接收參數(shù)部念,
                    props: ['msg'],
                    // 注意弃酌,在props中定義的屬性,都可以在 組件中直接使用
                    template: '<div style="border:2px solid red;height:70px;">{{msg}}</div>'
                },
                'bind-component': {
                    // 在組件中使用props來從父親組件接收參數(shù)印机,
                    props: ['msg'],
                    // 注意,在props中定義的屬性门驾,都可以在 組件中直接使用
                    template: '<div style="border:2px solid red;height:70px;">{{msg}}</div>'
                }
            },
        })
    </script>

使用不使用v-bind的區(qū)別 :

 在父組件里向子組件傳遞消息:
    <div id="app" style="border:2px solid green;height:400px;">
        <h5 style="text-align:center">我是父組件</h5>
        <child-component msg="我是來自父組件的內(nèi)容"></child-component>
        <hr><br>
        <!-- v-bing 對照試驗(yàn) 傳遞數(shù)組  -->
        v-bind對照試驗(yàn) 傳遞數(shù)組
        <!-- msg.length 是7 -->
        <child-component msg="[3,6,7]"></child-component>
        <!-- 使用v-bind可以識別為數(shù)組     msg.length 是3 -->
        <child-component :msg="[3,6,7]"></child-component>
        <br>
        <hr>使用v-bind進(jìn)行數(shù)據(jù)動(dòng)態(tài)綁定 把input中的msg傳遞給子組件
        <input type="text" v-model="parentmsg">
        <bind-component :msg="parentmsg"></bind-component>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    <script>
        // 一個(gè)父組件 
        var app = new Vue({
            el: '#app',
            data: {
                parentmsg: '今晚的月亮真圓啊'
            },
            // 定義一個(gè)子組件
            components: {
                'child-component': {
                    // 在組件中使用props來從父親組件接收參數(shù)射赛,
                    props: ['msg'],
                    // 注意,在props中定義的屬性奶是,都可以在 組件中直接使用
                    template: '<div style="border:2px solid red;height:70px;">{{msg}}</div>'
                },
                'bind-component': {
                    // 在組件中使用props來從父親組件接收參數(shù)楣责,
                    props: ['msg'],
                    // 注意竣灌,在props中定義的屬性,都可以在 組件中直接使用
                    template: '<div style="border:2px solid red;height:70px;">{{msg}}</div>'
                }
            },
        })
    </script>

單向數(shù)據(jù)流

解釋 : 通過 props 傳遞數(shù)據(jù) 是單向的了秆麸, 也就是父組件數(shù)據(jù)變化時(shí)會(huì)傳遞給子組
件初嘹,但是反過來不行。
目的 :是盡可能將父子組件解耦沮趣,避免子組件無意中修改了父組件的狀態(tài)屯烦。
應(yīng)用場景: 業(yè)務(wù)中會(huì)經(jīng)常遇到兩種需要改變 prop的情況

一種是父組件傳遞初始值進(jìn)來,子組件將它作為初始值保存起來房铭,在自己的作用域
下可以隨意使用和修改驻龟。這種情況可以在組件 data內(nèi)再聲明一個(gè)數(shù)據(jù),引用父組件的 prop

  • 步驟一:注冊組件
  • 步驟二:將父組件的數(shù)據(jù)傳遞進(jìn)來缸匪,并在子組件中用props接收
  • 步驟三:將傳遞進(jìn)來的數(shù)據(jù)通過初始值保存起來
    小栗子:
 <div id="app" style="border:2px solid green;height:400px;">
        <my-component msg="我是父組件傳遞的數(shù)據(jù)"></my-component>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>

    <script>
        // 步驟一:注冊組件
        Vue.component('my-component', {
            // 步驟二: 將父組件的數(shù)據(jù)傳遞進(jìn)來翁狐, 并在子組件中用props接收
            props: ['msg'],
            template: ' <div>{{count}}</div>',
            data: function() {
                return {
                    // 步驟三: 將傳遞進(jìn)來的數(shù)據(jù)通過初始值保存起來
                    // <!-- props的值可以通過this.xxx  直接進(jìn)行獲取-->
                    count: this.msg
                }
            },
        })
        var app = new Vue({
            el: '#app',
            data: {

            }
        })
    </script>

另一種情況就是 prop 作為需要被轉(zhuǎn)變的原始值傳入。這種情況用計(jì)算屬性就可以了

步驟一:注冊組件
步驟二:將父組件的數(shù)據(jù)傳遞進(jìn)來凌蔬,并在子組件中用props接收
步驟三:將傳遞進(jìn)來的數(shù)據(jù)通過計(jì)算屬性進(jìn)行重新計(jì)算
小栗子:

 <div id="app" style="border:2px solid green;height:400px;">
        <my-component msg="我是父組件傳遞的數(shù)據(jù)"></my-component>
        <hr> <br>
        <!-- 需求 :通過input中輸入的數(shù)據(jù)動(dòng)態(tài)改變div的寬度 -->
        <!-- 傳遞的數(shù)據(jù)僅僅是一個(gè)數(shù)據(jù)  需要計(jì)算屬性重新計(jì)算拼接 -->
        <input type="text" v-model="width">
        <width-component :width="width"></width-component>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>

    <script>
        //  場景一 步驟一:注冊組件
        Vue.component('my-component', {
                // 步驟二: 將父組件的數(shù)據(jù)傳遞進(jìn)來露懒, 并在子組件中用props接收
                props: ['msg'],
                template: ' <div>{{count}}</div>',
                data: function() {
                    return {
                        // 步驟三: 將傳遞進(jìn)來的數(shù)據(jù)通過初始值保存起來
                        // <!-- props的值可以通過this.xxx  直接進(jìn)行獲取-->
                        count: this.msg
                    }
                },
            })
            //  場景二 步驟一:注冊組件
        Vue.component('width-component', {
            // 步驟二: 將父組件的數(shù)據(jù)傳遞進(jìn)來, 并在子組件中用props接收
            props: ['width'],
            template: ' <div :style="style"></div>',
            data: function() {
                return {

                }
            },
            computed: {
                style: function() {
                    // return 出來的就是直接拼接好的style
                    return {
                        width: this.width + 'px',
                        background: 'red',
                        height: '300px'
                    }
                }
            }
        })
        var app = new Vue({
            el: '#app',
            data: {
                width: 0
            }
        })
    </script>

數(shù)據(jù)驗(yàn)證

vue組件中camelCased(駝峰式) 命名與kebab-case(短橫線命名)
  • html中, myMessagemymessage 是一致的,,因此在組件中的html
    中使用必須使用kebab-case(短橫線)命名方式砂心。在html中不允許使用駝
    峰P复省!<品 G账!躁倒! (謹(jǐn)記)
  • 在組件中, 父組件給子組件傳遞數(shù)據(jù)必須用短橫線荞怒。在template中,必
    須使用駝峰命名方式秧秉,若為短橫線的命名方式褐桌。則會(huì)直接保錯(cuò)。
  • 在組件的data中,用this.XXX引用時(shí),只能是駝峰命名方式象迎。若為短橫線
    的命名方式荧嵌,則會(huì)報(bào)錯(cuò)。
    小栗子:
 <div id="app" style="border:2px solid green;height:400px;">
        <!-- 會(huì)報(bào)錯(cuò)   Unknown custom element: myComponent  在組件中的`html`中使用必須使用`kebab-case`(短橫線)命名方式砾淌。在`html`中不允許使用駝峰@泊椤!-->
        <myComponent myMsg='lalalalal'></myComponent>
        <!-- 正確方式 在組件中, 父組件給子組件傳遞數(shù)據(jù)必須用短橫線汪厨。-->
        <my-component my-msg='lalalalal'></my-component>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>

    <script>
        Vue.component('myComponent', {
                props: ['myMsg'],
                //    在template中赃春, 必須使用駝峰命名方式, 若為短橫線的命名方式劫乱。 則會(huì)直接保錯(cuò)织中。
                template: ' <div>{{abc}}</div>',
                data: function() {
                    return {
                        // 在組件的data中,用this.XXX引用時(shí),只能是駝峰命名方式锥涕。若為短橫線的命名方式, 則會(huì)報(bào)錯(cuò)狭吼。
                        // abc: this.my - msg
                        // 正確的寫法
                        abc: this.myMsg
                    }
                },
            })
        var app = new Vue({
            el: '#app',
            data: {
                a: '100',
                b: '666',
                c: true

            }
        })
    </script>

驗(yàn)證的 type 類型可以是:

? String
? Number
?Boolean
? Object
? Array
?Function
栗子:

 <div id="app" style="border:2px solid green;height:400px;">
        <input type="text" v-model='d'>
        <br>
        <type-component :a='a' :b='b' :c='c' :d='d' :e='e' :f='f' :g='g'></type-component>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>

    <script>
            // 數(shù)組驗(yàn)證
        Vue.component('typeComponent', {
            // 約定值的類型
            props: {
                a: String,
                b: [String, Number],
                // 必須是布爾類型 默認(rèn)值是true typr required default
                c: {
                    type: Boolean,
                    default: true
                },
                d: {
                    type: Number,
                    // 必選項(xiàng)為true 必須傳值進(jìn)行渲染
                    required: true
                },
                // 不向子組件傳遞 就會(huì)取默認(rèn)值 default
                e: {
                    type: Array,
                    default: function() {
                        return ['666e', 333]
                    }
                },
                //自定義驗(yàn)證函數(shù)
                f: {
                    validator: function(value) {
                        return value > 10
                    }
                },
                //驗(yàn)證選項(xiàng)必須為function
                g: {
                    type: Function
                }
            },
            template: ' <div>{{a}}-----{层坠} -----{{c}}----{eapyjqs} ------{{e[0]}}----{{f}} -----{{g}}</div>',
            data: function() {
                return {}
            },
        })
        var app = new Vue({
            el: '#app',
            // 與上面的props中的選項(xiàng)對應(yīng) 
            data: {
                a: '100a',
                // String或者是Number
                b: '666b',
                // 默認(rèn)值為true
                c: '',
                // Missing required prop: "d"
                d: 66622,
                // 數(shù)組
                e: [],
                //自定義驗(yàn)證函數(shù) value > 10 就是 88 > 10  就會(huì)渲染
                f: 88,
                // 驗(yàn)證類型為function
                g: console.log("我是一個(gè)函數(shù)")

            }
        })
    </script>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市刁笙,隨后出現(xiàn)的幾起案子破花,更是在濱河造成了極大的恐慌,老刑警劉巖采盒,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件旧乞,死亡現(xiàn)場離奇詭異,居然都是意外死亡磅氨,警方通過查閱死者的電腦和手機(jī)尺栖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來烦租,“玉大人延赌,你說我怎么就攤上這事〔娉鳎” “怎么了挫以?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長窃祝。 經(jīng)常有香客問我掐松,道長,這世上最難降的妖魔是什么粪小? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任大磺,我火速辦了婚禮,結(jié)果婚禮上探膊,老公的妹妹穿的比我還像新娘杠愧。我一直安慰自己,他們只是感情好逞壁,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布流济。 她就那樣靜靜地躺著,像睡著了一般腌闯。 火紅的嫁衣襯著肌膚如雪绳瘟。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天姿骏,我揣著相機(jī)與錄音糖声,去河邊找鬼。 笑死芯丧,一個(gè)胖子當(dāng)著我的面吹牛映跟,可吹牛的內(nèi)容都是我干的九昧。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蟋恬,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了趁冈?” 一聲冷哼從身側(cè)響起歼争,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎渗勘,沒想到半個(gè)月后沐绒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡旺坠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年乔遮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片取刃。...
    茶點(diǎn)故事閱讀 39,902評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蹋肮,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出璧疗,到底是詐尸還是另有隱情坯辩,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布崩侠,位于F島的核電站漆魔,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏却音。R本人自食惡果不足惜改抡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望僧家。 院中可真熱鬧雀摘,春花似錦、人聲如沸八拱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽肌稻。三九已至清蚀,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間爹谭,已是汗流浹背枷邪。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留诺凡,地道東北人东揣。 一個(gè)月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓践惑,卻偏偏與公主長得像,于是被迫代替她去往敵國和親嘶卧。 傳聞我的和親對象是個(gè)殘疾皇子尔觉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評論 2 354

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

  • 組件(Component)是Vue.js最核心的功能,也是整個(gè)架構(gòu)設(shè)計(jì)最精彩的地方芥吟,當(dāng)然也是最難掌握的侦铜。...
    六個(gè)周閱讀 5,606評論 0 32
  • vue概述 在官方文檔中,有一句話對Vue的定位說的很明確:Vue.js 的核心是一個(gè)允許采用簡潔的模板語法來聲明...
    li4065閱讀 7,216評論 0 25
  • 什么是組件钟鸵? 組件 (Component) 是 Vue.js 最強(qiáng)大的功能之一钉稍。組件可以擴(kuò)展 HTML 元素,封裝...
    youins閱讀 9,480評論 0 13
  • 在這一節(jié)里棺耍,我們將會(huì)了解到Vue的組件贡未,理解組件是如何工作的,并利用一系列的例子證明蒙袍,用組件化的思想開發(fā)項(xiàng)目羞秤,會(huì)給...
    嘉寶_Appian閱讀 3,273評論 6 17
  • 今天開了個(gè)好頭,我一邊和謙寶斗智斗勇左敌,一邊拿出看過的文案書籍瘾蛋,挑選出幾個(gè)概念,用自己的方式做輸出矫限,然后同步到輕社群...
    謙奈兒閱讀 139評論 0 2