Vue自定義組件以及組件通訊的幾種方式

本帖子來源:小賢筆記css

功能html

組件 (Component) 是 Vue.js 最強大的功能之一。組件能夠擴展 HTML 元素,封裝可重用的代碼。在較高層面上,組件是自定義元素,Vue.js 的編譯器爲它添加特殊功能。在有些狀況下,組件也能夠表現爲用 is 特性進行了擴展的原生 HTML 元素。全部的 Vue 組件同時也都是 Vue 的實例,因此可接受相同的選項對象 (除了一些根級特有的選項) 並提供相同的生命週期鉤子vue

組件註冊api

組件名數組

組件名應該始終是多個單詞的,根組件 App 除外app

這樣作能夠避免跟現有的以及將來的 HTML 元素相沖突,由於全部的 HTML 元素名稱都是單個單詞的函數

單文件組件的文件名應該要麼始終是單詞大寫開頭 (PascalCase),要麼始終是橫線鏈接 (kebab-case)ui

混用文件命名方式有的時候會致使大小寫不敏感的文件系統的問題,這也是橫線鏈接命名一樣徹底可取的緣由this

  • 使用 kebab-case
    當使用 kebab-case (短橫線分隔命名) 定義一個組件時,你也必須在引用這個自定義元素時使用 kebab-case,例如 <my-component-name>

Vue.component('my-component-name', { /* ... */ })spa

  • 使用 PascalCase
    當使用 PascalCase (駝峯式命名) 定義一個組件時,你在引用這個自定義元素時兩種命名法均可以使用。也就是說 <my-component-name> 和 <MyComponentName> 都是可接受的。注意,儘管如此,直接在 DOM (即非字符串的模板) 中使用時只有 kebab-case 是有效的

Vue.component('MyComponentName', { /* ... */ })

全局註冊

以上方法都屬於全局註冊, 也就是說它們在註冊以後能夠用在任何新建立的 Vue 根實例 (new Vue) 的模板中, 好比

  • HTML

<divid="app">

<component-a></component-a>

<component-b></component-b>

<component-c></component-c>

</div>

  • JS

Vue.component('component-a', { /* ... */ })

Vue.component('component-b', { /* ... */ })

Vue.component('component-c', { /* ... */ })

 

new Vue({ el: '#app' })

在全部子組件中也是如此,也就是說這三個組件在各自內部也均可以相互使用

 

局部註冊

若是不須要全局註冊,或者是讓組件使用在其它組件內,能夠用選項對象的 components 屬性實現局部註冊, 這裏不作詳述

ps:具體參考博客vue由淺入深組件的其餘內容

父子組件通訊

: 本節引用歲月如同馬匹 - 簡書

在vue組件通訊中其中最多見通訊方式就是父子組件之中的通性,而父子組件的設定方式在不一樣狀況下又各有不一樣。最多見的就是父組件爲控制組件子組件爲視圖組件。父組件傳遞數據給子組件使用,遇到業務邏輯操做時子組件觸發父組件的自定義事件。不管哪一種組織方式父子組件的通訊方式都是大同小異

父組件到子組件通信

父組件到子組件的通信主要爲:子組件接受使用父組件的數據,這裏的數據包括屬性和方法(String, Number, Boolean, Object, Array, Function)。vue提倡單項數據流,所以在一般狀況下都是父組件傳遞數據給子組件使用,子組件觸發父組件的事件,並傳遞給父組件所須要的參數

經過 props 傳遞數據 (推薦)

父子通信中最多見的數據傳遞方式就是經過props傳遞數據,就好像方法的傳參同樣,父組件調用子組件並傳入數據,子組件接受到父組件傳遞的數據進行驗證使用

props 能夠是數組或對象,用於接收來自父組件的數據。props 能夠是簡單的數組,或者使用對象做爲替代,對象容許配置高級選項,如類型檢測、自定義校驗和設置默認值

prop 的定義應該儘可能詳細,至少須要指定其類型

<!-- 父組件 -->

<template>

<div>

<my-child:parentMessage="parentMessage"></my-child>

</div>

</template>

 

<script>

import MyChild from'@components/common/MyChild'

 

exportdefault {

components: {

            MyChild

        },

        data() {

return {

parentMessage: "我是來自父組件的消息"

            }

        }

    }

</script>

<!-- 子組件 -->

<template>

<div>

<span>{{ parentMessage }}</span>

</div>

</template>

 

<script>

exportdefault {

props: {

parentMessage: {

type: String,

default: '默認顯示的信息'

// require: true // 必填

            }

        }

    }

</script>

//父組件顯示:我是來自父組件的消息。

 

經過 $on 傳遞父組件方法

經過$on傳遞父組件方法是組件通訊中經常使用的方法傳遞方式。它能夠與經過props傳遞方法達到相同的效果。相比於props傳遞function,它更加的直觀和顯示的表現出了調用關係

<!-- 父組件 -->

<template>

<div>

<my-child @childEvent="parentMethod"></my-child>

</div>

</template>

 

<script>

import MyChild from'@components/common/MyChild'

 

exportdefault {

components: {

            MyChild,

        },

        data() {

return {

parentMessage: '我是來自父組件的消息',

            }

        },

methods: {

            parentMethod() {

                alert(this.parentMessage)

            }

        }

    }

</script>

<!-- 子組件 -->

<template>

<div>

<h3>子組件</h3>

</div>

</template>

 

<script>

exportdefault{

        mounted() {

this.$emit('childEvent')

        }

    }

</script>

//先彈出一個窗口顯示  我是來自父組件的消息,而後父組件顯示文本是子組件

獲取父組件而後使用父組件中的數據(不推薦)

準確來講這種方式並不屬於數據的傳遞而是一種主動的查找。父組件並無主動的傳遞數據給子組件,而是子組件經過與父組件的關聯關係,獲取了父組件的數據
該方法雖然能實現獲取父組件中的數據可是不推薦這種方式,由於vue提倡單向數據流,只有父組件交給子組件的數據子組件纔有使用的權限,不容許子組件私自獲取父組件的數據進行使用。在父與子的關係中子應當是處於一種被動關係

// 此處的this爲子組件實例

this.$parent

子組件到父組件通信

子組件到父組件的通信主要爲父組件如何接受子組件之中的數據。這裏的數據包括屬性和方法(String, Number, Boolean, Object, Array, Function)

經過 $emit 傳遞父組件數據 (推薦)

與父組件到子組件通信中的$on配套使用,能夠向父組件中觸發的方法傳遞參數供父組件使用

<!-- 父組件 -->

<template>

<div>

<my-child @childEvent="parentMethod"></my-child>

</div>

</template>

 

<script>

import MyChild from'@components/common/MyChild'

 

exportdefault {

components: {

            MyChild

        },

        data() {

return {

parentMessage: '我是來自父組件的消息'

            }

        },

methods: {

            parentMethod({ name, age }) {

console.log(this.parentMessage, name, age)

            }

        }

    }

</script>

<!-- 子組件 -->

<template>

<div>

<h3>子組件</h3>

</div>

</template>

 

<script>

exportdefault {

        mounted() {

this.$emit('childEvent', { name: 'zhangsan', age:  10 })

        }

    }

</script>

//父組件顯示文本爲子組件,控制檯輸出:我是來自父組件的消息  zhangsan 10

refs 獲取

能夠經過在子組件添加ref屬性,而後能夠經過ref屬性名稱獲取到子組件的實例。準確來講這種方式和 this.$parent 同樣並不屬於數據的傳遞而是一種主動的查找。

儘可能避免使用這種方式。由於在父子組件通訊的過程當中。父組件是處於高位是擁有控制權,而子組件在多數狀況下應該爲純視圖組件,只負責視圖的展現和自身視圖的邏輯操做。對外交互的權利應該由父組件來控制。因此應當由父組件傳遞視圖數據給子組件,子組件負責展現。而子組件的對外交互經過$emit觸發父組件中相應的方法,再由父組件處理相應邏輯

<!-- 父組件 -->

<template>

<div>

<my-child ref="child"></my-child>

</div>

</template>

 

<script>

import MyChild from'@components/common/MyChild'

 

exportdefault {

components: {

            MyChild

        },

        mounted() {

console.log(this.$refs['child'].getData());

        }

    }

</script>

<!-- 子組件 -->

<script>

exportdefault {

methods: {

            getData() {

// do something...

            }

        }

    }

</script>

//子組件在getdata函數中傳輸的會顯示在父組件,而且會返回getdata函數

組件樣式修改

參考文章CSS 做用域

若是你但願 scoped 樣式中的一個選擇器可以做用得「更深」,例如影響子組件,你可使用 >>> 操做符:

<style scoped>

.a>>>.b { /* ... */ }

</style>

上述代碼將會編譯成:

.a[data-v-f3f3eg9].b { /* ... */ }

有些像 Sass 之類的預處理器沒法正確解析 >>>。這種狀況下你可使用 /deep/ 操做符取而代之——這是一個 >>> 的別名,一樣能夠正常工做

<style scoped>

    .a /deep/ .b { /* ... */ }

</style>

相關文章
相關標籤/搜索