Vue组件间通信

javascript/jquery

浏览数:177

2020-6-16

组件间通信

父组件 => 子组件

  • 属性props
// child
props: { msg: string }

// parent
<HelloWorld msg="welcome"></HelloWorld>
  • 特性$attrs
// child 并未在props中声明foo
<p>{{$attrs.foo}}</p>

// parent
<HelloWorld foo="foo"></HelloWorld>
  • 引用refs
// parent
<HelloWorld ref="pj"></HelloWorld>
mounted(){
    this.$refs.pj.test = 'xxx'
}
  • 子元素$children(子元素不保证顺序)
// parent
this.$children[0].test = 'xxxxx'

子组件 => 父组件:自定义事件

// child
this.$emit('add',good)

// parent
<HelloWorld @add="otherAdd($event)"></HelloWorld>

兄弟组件:通过共同的祖辈组件

通过共同的祖辈组件搭桥,$parent或$root

// brother1
this.$parent.$on('foo',handle)
// brother2
this.$parent.$emit('foo')

祖先和后代之间

由于嵌套层数过多,传递props不切实际,vue提供了provide/inject API完成任务

  • provide/inject:能够实现祖先给后代传值
// grandparent
provide(){
    return {
        foo: 'foo'
    }
}

// child
inject: ['foo']

任意两个组件之间:事件总线和vuex

  • 事件总线,创建一个Bus类负责事件派发,监听和回调处理
// Bus: 事件派发、监听和回调管理
class Bus{
    constructor(){
        this.callbacks = {}
    }
    $on(name,fn){
        this.callbacks[name] = this.callbacks[name] || []
        this.callbacks[name].push(fn)
    }
    $emit(name,args){
        if(this.callbacks[name]){
            this.callbacks[name].forEach(cb => cb(args))
        }
    }
}

// main.js
Vue.prototype.$bus = new Bus()

// child1.js
this.$bus.$on('foo',handle)

// child2.js
this.$bus.$emit('foo')
  • vuex:创建唯一的全局数据管理者store,通过它管理数据并通知组件状态变更

双向绑定的实现

// 方法一:
// 子组件
<input type="text" :value="value" @input="onInput">

methods: {
    onInput(e){
        this.$emit('input',e.taget.value)
    }
}

// 父组件
<KInput v-model="username"></KInput>

// 方法二:
// 子组件
<input type="text" :value="value" @input="onInput">

methods: {
    onInput(e){
        this.$emit('updata:value',e.taget.value)
    }
}

// 父组件
<KInput :value.sync="username"></KInput>

双向绑定的原理 VUE实现双向数据绑定的原理就是利用了 Object.defineProperty() 这个方法重新定义了对象获取属性值(get)和设置属性值(set)的操作来实现的

作者:洁本佳人