Vue入門指南-07 Vue中的元件(快速上手vue)

番茄炒蛋少放糖發表於2019-03-30

學習元件,我們首先要了解什麼是元件。元件是Vue可以複用的Vue例項,且帶有一個名字,在Vue中我們可以定義多個元件,在多個不同的頁面的中引用多個多不同的元件,減少開發的工作量。因為元件是可複用的Vue例項,所以它們與new Vue接收相同的選項,例如:data,computed,watch,methods以及生命週期鉤子等等,僅有的例外是像el這樣根例項特有的選項。

建立元件的幾種方式

  • 第一種使用Vue.extend來建立全域性的Vue元件
// 建立元件模版物件
let mycomponent = Vue.extend({
    // 通過template屬性指定了元件要展示的HTML結構
    template:"<div>我是使用Vue.extend建立的元件</div>" // 
})

// 使用Vue.component("元件名稱", 建立出來的元件模版物件)
Vue.component("custom", mycomponent) 

// 直接把元件的名稱以HTML標籤的形式引入到頁面中就可以使用了
<custom></custom> 
複製程式碼

注意 :不論是那種方式建立出來的元件,元件的template屬性指向的模版內容,必須有且只能有一個唯一的根元素。

注意 :在使用Vue.component定義全域性元件的時候,元件名稱使用駝峰命名,則在引用元件的時候,需要把大寫的駝峰改為小寫的字母,同時兩個單詞之間使用 - 連線,例如:

Vue.component("customLabel", mycomponent) // 元件名稱駝峰命名
<custom-label></custom-label> // 駝峰改為小寫的字母,同時兩個單詞之間使用 - 連線
複製程式碼

註冊全域性元件引用的簡寫方式:

Vue.component("custom", Vue.extend({
    // 通過template屬性指定了元件要展示的HTML結構
    template:"<div>我是使用Vue.extend建立的元件</div>" // 
})) 
複製程式碼
  • 第二種使用Vue.component建立全域性的Vue元件
Vue.component("custom", {
    // 通過template屬性指定了元件要展示的HTML結構
    template:"<div>我是使用Vue.component建立的元件</div>" // 
})

// 通過Vue.component的另一種書寫方式建立全域性元件
Vue.component("custom", {template:"#tmp"}) //  template屬性指向一個id
// 在被控制的Vue例項el繫結的元素外,使用template元素定義元件的HTML模版結構
<template id="tmp">
    <div>
        <h1>我是Vue.component建立全域性元件的第二種方式</h1>
    </div>
</template>
複製程式碼
  • 第三種通過Vue例項的components屬性建立Vue區域性元件(例項內部私有元件)
<div id="app">
    <custom>/custom>
    <customTwo></customTwo>
    <customThree></customThree>
</div>
<template id="tmp">
    <div>
        <h1>我是components建立的區域性元件利用template元素</h1>
    </div>
</template>
<script>
    let customThree = {
        template: "<div><h1>我是Vue例項外建立的元件模版物件</h1></div>"
    }
    new Vue({
    el: "#app",
    components: {
        // 第一種方式
        "custom": {template:"<div><h1>我是components建立的區域性元件</h1></div>"},
        // 第二種方式
        "customTwo"{template:"#tmp"},
        // 第三種方式
        "customThree": customThree // 自定義元件名稱和元件模版物件名稱一致可以簡寫為一個
    }
})
</script>
複製程式碼

注意 : 元件中也可以定義資料和屬性

// 但是元件中的data和例項中的data不一樣,例項中的data可以為一個物件,但元件中的data必須是一個方法。
// 這個方法內部還必須return一個物件出來才行。
// 元件中data的資料和例項中data資料的使用方式完全一樣
// 例如:
new Vue({
    el: "#app",
    data: {
        msg: "我是例項中data的資料"
    }
})
Vue.components("custom",{
    template:"<div> <h1>{{ msg }}</h1></div>",
    data () {
        return {
            msg: "我是元件中data的資料"
        }
    }
})
複製程式碼

Vue提供了components元素來展示對應名稱的元件

// components是一個佔位符, :is 屬性可以用來指定要展示的元件名稱
// 注意 :is 屬性的值為要展示的元件名稱,但是也可以寫成一個變數,方便某些時候動態切換要展示的元件。
<div id="app">
    <component :is="msg"></component>
    <button @click="change">切換元件</button>
</div>
<script>
    new Vue({
    el: "#app",
    data: {
        msg: "custom"
    },
    components: {
        "custom": {template:"<div><h1>我是components建立的區域性元件custom</h1></div>"},
        "customTwo": {template:"<div><h1>我是components建立的區域性元件customTwo</h1></div>"}
    },
    methods: {
        change () {
            // 通過chage方法動態改變msg的值來切換要展示的元件
        }
    }
})
</script>
複製程式碼

元件通訊 => 父子元件,兄弟元件之間通訊

  • 元件通訊中,子元件是無法訪問到父元件中的資料和方法的。
  • 父元件可以在引用子元件的時候,通過屬性繫結(v-bind)的形式,把資料傳遞給子元件使用。
  • 父元件通過自定義屬性傳過來的資料,需要子元件在props屬性上接收才能使用。

父傳子值

<div id="app">
    <custom :parentmsg="msg"></custom>
</div>
<script>
    new Vue({
    el: "#app",
    data: {
        msg: "我是父元件中的資料"
    },
    components: {
        "custom": {
            props: ["parentmsg"],// 子元件通過props屬性接收父元件傳來的資料
            template:"<div><h1>我要引用父元件中的資料----{{ parentmsg }}</h1></div>"
        }
    }
})
</script>
複製程式碼

父傳子方法, 子傳父資料

父元件向子元件傳遞方法,使用的是事件繫結機制v-on,當我們自定義事件屬性後,那麼子元件就可以通過某些方式來呼叫父元件傳遞的這個方法。

<div id="app">
    // 通過自定義事件名稱func以事件繫結機制@func="show"將父元件的show方法傳遞給子元件
    <custom @func="show"></custom> 
</div>
<script>
    new Vue({
    el: "#app",
    data: {
        msg: "我是父元件中的資料"
    },
    components: {
        "custom": {
            props: ["parentmsg"],// 子元件通過props屬性接收父元件傳來的資料
            data () {
                return {
                    childmsg: "我是子元件的資料"
                }
            },
            template:`
                <div>
                    <h1>我要呼叫父元件傳遞過來的方法</h1>
                    <button @click="emit">點我呼叫父元件傳遞的方法</button>
                </div>`,
            methods: {
                emit () {
                    // 觸發父元件傳過來的func方法,配合引數可以將子元件的資料傳遞給父元件
                    // vm.$emit(evebtNane, [...args]) 觸發當前例項上的事件,附加引數會傳給監聽器回撥。
                    this.$emit("func",this.childmsg) 
                }
            }
        },
    },
    methods: {
        // 子元件觸發了我,並且給我傳遞了子元件的資料data
        show (data) {
            console.log("我是父元件中的show方法")
            console.log("接收到了子元件傳遞的資料---" + data)
        }
    }
})
</script>
複製程式碼
  • 注意元件中所有props屬性中的資料,都是通過父元件傳遞給子元件的。
  • props中的資料都是隻讀不可寫的,data上的資料都是可讀可寫的,
  • 子元件中data中的資料,並不是通過父元件傳遞過來的,而是子元件自己私有的。

兄弟元件之間資料傳遞

  • 第一種藉助中央事件匯流排
<div id="app">
    
</div>
<script>
    // 重新例項一個Vue
    let Bus = new Vue()
    
    new Vue({
        el: "#app",
        components: {
            "custom": {
                template:`<div @click = sendMsg>
                    <button>點我給customTwo元件傳遞我的資料</button>
                </div>`,
                data () {
                    return {
                        msg: "我是custom元件的資料"
                    }
                },
                methods: {
                    sendMsg () {
                        Bus.$emit("myFunc", this.msg) // $emit這個方法會觸發一個事件
                    }
                }
            },
            "customTwo": {
                template:`<div>
                    <h1>下面是我接收custom元件傳來的資料</h1>
                    <p>{{ customTwoMsg }}</p>
                </div>`,
                data () {
                    return {
                        customTwoMsg: ""
                    }
                },
                created () {
                    this.brotherFunc()
                },
                methods: {
                    brotherFunc () {
                        Bus.$on("myFunc", (data) => { // 這裡要用箭頭函式,否則this指向有問題。
                            this.customTwoMsg = data
                        })
                    }
                }
            }
        }
    })
</script>
複製程式碼

這樣藉助匯流排機制,實現兄弟元件之間的資料共享。

  • 第二種藉助第三方vuex庫(這是我推薦使用的)

Vuex 是一個專為 Vue.js 應用程式開發的狀態管理模式。它採用集中式儲存管理應用的所有元件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。Vuex 也整合到 Vue 的官方除錯工具 devtools extension,提供了諸如零配置的 time-travel 除錯、狀態快照匯入匯出等高階除錯功能。

具體用法請檢視vuex官方文件超級詳細。

Vue入門指南(快速上手vue)

相關文章