vue 組件基礎(chǔ)

祭出demo

基礎(chǔ)示例

組件是可復(fù)用的 Vue 實(shí)例,所以它們與 new Vue 接收相同的選項(xiàng),例如 data、computed、watch、methods 以及生命周期鉤子等。僅有的例外是像 el 這樣根實(shí)例特有的選項(xiàng)。

組件的復(fù)用

你可以將組件進(jìn)行任意次數(shù)的復(fù)用:

  • data必須是個(gè)函數(shù)
    當(dāng)我們定義這個(gè) <button-counter> 組件時(shí),你可能會(huì)發(fā)現(xiàn)它的 data選項(xiàng)必須是一個(gè)函數(shù),
    因此每個(gè)實(shí)例可以維護(hù)一份被返回對(duì)象的獨(dú)立的拷貝

通過prop向子組件傳遞數(shù)據(jù)

Prop 是你可以在組件上注冊(cè)的一些自定義特性。當(dāng)一個(gè)值傳遞給一個(gè) prop 特性的時(shí)候,它就變成了那個(gè)組件實(shí)例的一個(gè)屬性。為了給博文組件傳遞一個(gè)標(biāo)題,我們可以用一個(gè) props 選項(xiàng)將其包含在該組件可接受的 prop 列表中:

單個(gè)根元素

一個(gè)組件里,只能有一個(gè)根元素,負(fù)責(zé)會(huì)報(bào)錯(cuò)

通過事件向父組件發(fā)送消息

我們可以調(diào)用內(nèi)建的 $emit 方法并傳入事件的名字,來向父級(jí)組件觸發(fā)一個(gè)事件。
這里需要注意的是:父類組件綁定的事件名大小寫不敏感的,但是在子組件里發(fā)送消息時(shí)必須要使用全部小寫的方式發(fā)送消息,否則無法成功發(fā)送消息。比如:父組件綁定事件v-on:myPlay="playGame",子組建立調(diào)用時(shí)就是:$emit("myplay"),或者父子組件的事件名都是帶短線的寫法也是可以的。

  • 使用事件拋出一個(gè)值
    可以使用 emit 的第二個(gè)參數(shù)來提供這個(gè)值。例如:emit("myplay","play football")。然后當(dāng)在父級(jí)組件監(jiān)聽這個(gè)事件的時(shí)候,我們可以通過 $event 訪問到被拋出的這個(gè)值:

*組件上使用v-model

插槽分發(fā)內(nèi)容

Vue 自定義的 <slot> 元素可以實(shí)現(xiàn)插槽分發(fā)內(nèi)容

動(dòng)態(tài)組件

你可以在這里查閱并體驗(yàn)完整的代碼,或在這個(gè)版本了解綁定組件選項(xiàng)對(duì)象,而不是已注冊(cè)組件名的示例。

示例代碼:

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <title>組件基礎(chǔ)</title>
        <script src="../static/vue.js" type="text/javascript" charset="utf-8"></script>
    </head>

    <body>
        <div id="app">
            <!--組件是可復(fù)用的 Vue 實(shí)例,且?guī)в幸粋€(gè)名字:在這個(gè)例子中是 <button-counter>。
                我們可以在一個(gè)通過 new Vue 創(chuàng)建的 Vue 根實(shí)例中,把這個(gè)組件作為自定義元素來使用:
                因?yàn)榻M件是可復(fù)用的 Vue 實(shí)例,所以它們與 new Vue 接收相同的選項(xiàng),例如 data、computed、
                watch、methods 以及生命周期鉤子等。僅有的例外是像 el 這樣根實(shí)例特有的選項(xiàng)。-->
            <button-counter></button-counter>
            <br />
            <!--組件的復(fù)用:
            你可以將組件進(jìn)行任意次數(shù)的復(fù)用:
            注意當(dāng)點(diǎn)擊按鈕時(shí),每個(gè)組件都會(huì)各自獨(dú)立維護(hù)它的 count。
            因?yàn)槟忝坑靡淮谓M件,就會(huì)有一個(gè)它的新實(shí)例被創(chuàng)建。-->
            <button-counter></button-counter>
            <button-counter></button-counter>
            <!--data 必須是一個(gè)函數(shù)
            當(dāng)我們定義這個(gè) <button-counter> 組件時(shí),你可能會(huì)發(fā)現(xiàn)它的 data選項(xiàng)必須是一個(gè)函數(shù),
                因此每個(gè)實(shí)例可以維護(hù)一份被返回對(duì)象的獨(dú)立的拷貝:-->

            <!--組件的組織:
            通常一個(gè)應(yīng)用會(huì)以一棵嵌套的組件樹的形式來組織:
            例如,你可能會(huì)有頁(yè)頭、側(cè)邊欄、內(nèi)容區(qū)等組件,每個(gè)組件又包含了其它的像導(dǎo)航鏈接、博文之類的組件。
            為了能在模板中使用,這些組件必須先注冊(cè)以便 Vue 能夠識(shí)別。這里有兩種組件的注冊(cè)類型:全局注冊(cè)和
            局部注冊(cè)。至此,我們的組件都只是通過 Vue.component 全局注冊(cè)的:-->
            <!--通過 Prop 向子組件傳遞數(shù)據(jù)-->
            <blog-post title="My journey with Vue"></blog-post>
            <blog-post title="Blogging with Vue"></blog-post>
            <blog-post title="Why Vue is so fun"></blog-post>
            <!--
                作者:zzhrainbow@163.com
                時(shí)間:2018-07-22
                描述:在一個(gè)典型的應(yīng)用中,你可能在 data 里有一個(gè)博文的數(shù)組:
            -->
            <blog-post v-for="post in posts" v-bind:title="post.title" v-bind:key="post.id"></blog-post>
            <!--通過事件向父級(jí)組件發(fā)送消息:
            在我們開發(fā) <blog-post> 組件時(shí),它的一些功能可能要求我們和父級(jí)
            組件進(jìn)行溝通。例如我們可能會(huì)引入一個(gè)可訪問性的功能來放大博文的字號(hào),
            同時(shí)讓頁(yè)面的其它部分保持默認(rèn)的字號(hào)。在其父組件中,我們可以通過添加一個(gè) 
            postFontSize 數(shù)據(jù)屬性來支持這個(gè)功能:-->
            <div v-bind:style="{fontSize:postFontSize + 'em'}">
                <blog-post-elements v-for="post in postElements" v-bind:post="post" v-bind:key="post.id" v-on:changeBigText="changeFontSize($event)">
                </blog-post-elements>
            </div>
            <!--使用事件拋出一個(gè)值
            有的時(shí)候用一個(gè)事件來拋出一個(gè)特定的值是非常有用的。例如我們可能想讓 <blog-post> 
                組件決定它的文本要放大多少。這時(shí)可以使用 $emit 的第二個(gè)參數(shù)來提供這個(gè)值:-->

            <!--通過插槽分發(fā)內(nèi)容:
                和 HTML 元素一樣,我們經(jīng)常需要向一個(gè)組件傳遞內(nèi)容,像這樣:
                幸好,Vue 自定義的 <slot> 元素讓這變得非常簡(jiǎn)單:-->
            <alert-box>
                Something bad happened.
            </alert-box>
            <!--動(dòng)態(tài)組件:
            可以通過 Vue 的 <component> 元素加一個(gè)特殊的 is 特性來實(shí)現(xiàn):-->

            <button v-for="tab in tabs" v-bind:key="tab" v-bind:class="['tab-button', { active: currentTab === tab }]" v-on:click="currentTab = tab">{{ tab }}</button>
            <component v-bind:is="currentTabComponent" class="tab"></component>

        </div>
        <script type="text/javascript">
            Vue.component("buttonCounter", {
                data() {
                    return {
                        count: 0,
                    }
                },

                template: "<button v-on:click='count++'>you clicked me {{count}} times</button>"
            })

            Vue.component('blog-post', {
                props: ['title'],
                template: '<h3>{{ title }}</h3>'
            })

            Vue.component('blog-post-elements', {
                props: ['post'],
                template: '<div ><h3>{{ post.title }}</h3> <button v-on:click="enlargeText" > enlarge text </button> <div v-html="post.content" > </div></div>',
                methods: {
                    enlargeText() {
                        this.$emit("changebigtext", 0.3) //注意這里的傳送事件與父組件里監(jiān)聽的事件名字的區(qū)別
                    }
                },

            })

            Vue.component('alert-box', {
                template: "<div class='demo - alert - box '><strong>Error!</strong><slot></slot> </div>"

            })

            Vue.component('tab-home', {
                template: '<div>Home component</div>'
            })
            Vue.component('tab-posts', {
                template: '<div>Posts component</div>'
            })
            Vue.component('tab-archive', {
                template: '<div>Archive component</div>'
            })

            var vm = new Vue({
                el: "#app",
                data: {
                    posts: [{
                            id: 1,
                            title: "first blog",
                        },
                        {
                            id: 2,
                            title: "second blog",
                        },
                        {
                            id: 3,
                            title: "third blog",
                        },
                    ],
                    postFontSize: 1,
                    postElements: [{
                            id: 2016,
                            content: "<p>1.為了變大數(shù)據(jù)</p>",
                        },
                        {
                            id: 2017,
                            content: "<p>2.第二條</p>",
                        },
                        {
                            id: 2018,
                            content: "<p>3.第三條來了</p>",
                        },

                    ],
                    currentTab: 'Home',
                    tabs: ['Home', 'Posts', 'Archive']
                },
                methods: {
                    changeFontSize(changeValue) {
                        this.postFontSize += changeValue
                    }
                },
                computed: {
                    currentTabComponent() {
                        return "tab-" + this.currentTab.toLowerCase()
                    }
                }
            })
        </script>

        <style type="text/css">
            .tab-button {
                padding: 6px 10px;
                border-top-left-radius: 3px;
                border-top-right-radius: 3px;
                border: 1px solid #ccc;
                cursor: pointer;
                background: #f0f0f0;
                margin-bottom: -1px;
                margin-right: -1px;
            }
            
            .tab-button:hover {
                background: lightgray;
            }
            
            .tab-button.active {
                background: lightgray;
            }
            
            .tab {
                border: 1px solid #ccc;
                padding: 10px;
                background: lightpink;
            }
        </style>

    </body>

</html>

運(yùn)行效果:


組件基礎(chǔ).png

祭出demo

參考:
vue.js 組件基礎(chǔ)

更新時(shí)間: 2018-07-22

?著作權(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)容

  • 組件是可復(fù)用的Vue實(shí)例,且?guī)в幸粋€(gè)名字。我們可以在一個(gè)通過new Vue創(chuàng)建的Vue根實(shí)例中,把這個(gè)組件作為自定...
    oWSQo閱讀 357評(píng)論 0 0
  • 這篇筆記主要包含 Vue 2 不同于 Vue 1 或者特有的內(nèi)容,還有我對(duì)于 Vue 1.0 印象不深的內(nèi)容。關(guān)于...
    云之外閱讀 5,177評(píng)論 0 29
  • 此文基于官方文檔,里面部分例子有改動(dòng),加上了一些自己的理解 什么是組件? 組件(Component)是 Vue.j...
    陸志均閱讀 3,947評(píng)論 5 14
  • 主要還是自己看的,所有內(nèi)容來自官方文檔。 介紹 Vue.js 是什么 Vue (讀音 /vju?/,類似于 vie...
    Leonzai閱讀 3,538評(píng)論 0 25
  • ORM,Object Relation Mapping,即對(duì)象關(guān)系映射。Hibernate就是ORM的實(shí)現(xiàn),使對(duì)象...
    Acamy丶閱讀 267評(píng)論 0 1

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