vue組件之間的通訊

前言

做爲一個vue初學者不得不瞭解的就是組件間的數據通訊(暫且不談vuex)。通訊方式根據組件之間的關係有不一樣之處。組件關係有下面三種:父-->子子-->父非父子vue

父-->子

父向子傳遞數據經過props
**父組件代碼**
<template>
    <header-box :title-txt="showTitleTxt"></header-box>
</template>
<script>
    import Header from './header'
    export default {
        name: 'index',
        components: {
            'header-box': Header
        },
        data () {
            return {
                showTitleTxt: '首頁'
            }
        }
    }
</script>
**子組件代碼**
<template>
    <header>
        {{thisTitleTxt}}
    </header>
</template>
<script>
    export default {
        name: 'header-box',
        props: {
            titleTxt: String
        },
        data () {
            return {
                thisTitleTxt: this.titleTxt
            }
        }
    }
</script>

子-->父

子組件向父組件傳遞分爲兩種類型。
一、子組件改變父組件傳遞的props(你會發現經過props中的Object類型參數傳輸數據,能夠經過子組件改變數據內容。這種方式是可行的,可是不推薦使用,由於官方定義prop是單向綁定)
二、經過$on和$emit
*經過props實現傳遞*
**父組件代碼**
<template>
    <header-box :title-txt="showTitleTxt"></header-box>
</template>
<script>
    import Header from './header'
    export default {
        name: 'index',
        components: {
            'header-box': Header
        },
        data () {
            return {
                showTitleTxt: {
                    name: '首頁'
                }
            }
        }
    }
</script>
**子組件代碼**
<template>
    <header @click="changeTitleTxt">
        {{thisTitleTxt.name}}
    </header>
</template>
<script>
    export default {
        name: 'header-box',
        props: {
            titleTxt: Object
        },
        data () {
            return {
                thisTitleTxt: this.titleTxt.name
            }
        },
        metheds: {
            changeTitleTxt () {
                this.titleTxt.name = '切換'
            }
        }
    }
</script>
*經過$on,$emit*
**父組件代碼**
<template>
    <div id="counter-event-example">
      <p>{{ total }}</p>
      <button-counter v-on:increment="incrementTotal"></button-counter>
</div>
</template>
<script>
    import ButtonCounter from './buttonCounter'
    export default {
        name: 'index',
        components: {
            'button-conuter': ButtonCounter
        },
        data () {
            return {
                total: 0
            }
        },
        methods: {
            incrementTotal () {
                this.total++
            }
        }
    }
</script>
**子組件代碼**
<template>
    <button @click="incrementCounter">{{counter}}</button>
</template>
<script>
    export default {
        name: 'button-counter',
        data () {
            return {
                counter: 0
            }
        },
        metheds: {
            incrementCounter () {
                this.$emit('increment')
                this.counter++
            }
        }
    }
</script>

非父子

簡單狀況下咱們能夠經過使用一個空的Vue實例做爲中央事件總線,(這裏也能夠使用app實例,而不須要新建一個空Vue實例)
**main.js**
let bus = new Vue()
Vue.prototype.bus = bus

或者vuex

**main.js**
new Vue({
  el: '#app',
  router,
  template: '<App/>',
  components: { App },
  beforeCreate () {
    Vue.prototype.bus = this
  }
})
**header組件**
<template>
    <header @click="changeTitle">{{title}}</header>
</template>
<script>
export default {
    name: 'header',
    data () {
        return {
            title: '頭部'
        }
    },
    methods: {
        changeTitle () {
            this.bus.$emit('toChangeTitle','首頁')
        }
    }
}
</script>
**footer組件**
<template>
    <footer>{{txt}}</footer>
</template>
<script>
export default {
    name: 'footer',
    mounted () {
        this.bus.$on('toChangeTitle', function (title) {
            console.log(title)
        })
    },
    data () {
        return {
            txt: '尾部'
        }
    }
}
相關文章
相關標籤/搜索