Vue組件通訊

父子通訊

props和emit

父組件經過props傳遞數據給子組件,子組件經過emit發送事件傳遞給父組件。html

// 父組件
<div>
    <child :data="child" @send="getFromChild"></child>
</div>

data(){
    return{
        toChild: '大兒子',
        fromChild: ''
    }
},
methods: {
    getFromChild(val){
        this.fromChild=val
    }
}
// 子組件
<div @click="toParent">{{data}}</div>

props:[data],
methods: {
    toParent(){
        this.$emit('send', '給父親')
    }
}

v-model

v-model實際上是props,emit的語法糖,v-model默認會解析成名爲value的prop和名爲input的事件。vue

// 父組件
<children v-model="msg"></children>
<p>{{msg}}</p>

data(){
    return{
        msg:'model'
    }
}
// 子組件
<input :value="value" @input="toInput" />

props: ['value'],
methods: {
    toInput(e){
        this.$emit('input', e.target.value)
    }
}

$children和$parent

在父組件使用$children訪問子組件,在子組件中使用$parent訪問父組件segmentfault

// 父組件
<child />

data(){
    return {
        msg: '父組件數據'
    }
},
methods: {
    test(){
        console.log('我是父組件的方法,被執行')
    }
},
mounted(){
    console.log(this.$children[0].child_msg); // 執行子組件方法
}
// 子組件
<div>{{$parent.msg}}</div>

data(){
    return{
        child_msg: '子組件數據'
    }
},
mounted(){
    // 子組件執行父組件方法
    this.$parent.test(); 
}

.sync方式

在vue1.x中是對prop進行雙向綁定,在vue2只容許單向數據流,也是一個語法糖dom

// 父組件
<child :count.sync="num" />

data(){
    return {
        num: 0
    }
}
// 子組件
<div @click="handleAdd">add</div>

data(){
    return {
        counter: this.count
    }
},
props: ["count"],
methods: {
    handleAdd(){
        this.$emit('update:count', ++this.counter)
    }
}

跨多層次組件通訊

依賴注入

能夠使用provide/inject,雖然文檔中不推薦直接使用在業務中。
假設有父組件A,而後有一個跨多層次的子組件Bide

// 父組件A
export default{
    provide: {
        data: 1
    }
}
// 子組件B
export default{
    inject: ['data'],
    mounted(){
        // 不管跨幾層都能獲取父組件的data屬性
        console.log(this.data); // 1
    }
}

$listeners和$attrs

$attrs--包含了父做用域中不做爲 prop 被識別 (且獲取) 的特性綁定 (class 和 style 除外)。
inheritAttrs--默認值true,繼承全部父組件屬性(除props),爲true會將attrs中的屬性當作html的data屬性渲染到dom根節點上
$listeners--包含了父做用域中的 (不含 .native 修飾器的) v-on 事件監聽器,v-on="$listeners"將全部事件監聽器指向這個組件的某個特定子元素post

// 父組件
<children :child1="child1" :child2="child2" @test1="onTest1"
@test2="onTest2"></children>

data(){
    return {
        child1: 'childOne',
        child2: 'childTwo'
    }
},
methods: {
    onTest1(){
        console.log('test1 running')
    },
    onTest2(){
        console.log('test2 running')
    }
}

// 子組件
<p>{{child1}}</p>
<child v-bind="$attrs" v-on="$listeners"></child>

props: ['child1'],
mounted(){
    this.$emit('test1')
}

// 孫組件
<p>{{child2}</p>
<p>{{$attrs}}</p>

props: ['child2'],
mounted(){
    this.$emit('test2')
}

任意組件

Event Bus

1.新建一個bus.js文件this

import Vue from 'vue';
export default new Vue();

2.使用它雙向綁定

<div @click="addCart">添加</div>
import Bus from 'bus.js';
export default{
    methods: {
        addCart(event){
            Bus.$emit('getTarget', event.target)
        }
    }
}
// 另外一組件
export default{
    created(){
        Bus.$on('getTarget', target =>{
            console.log(target)
        })
    }
}

Vue.observable

能夠做爲最小化跨組件狀態化管理。
使用Vue.observable()進行狀態管理code

Vuex方式

參考連接:
https://juejin.im/post/5c776e...
https://segmentfault.com/a/11...htm

相關文章
相關標籤/搜索