Vue中组件间传值总结 ------ 2020-05-17

2020-05-17  本文已影响0人  自己写了自己看

父子组件间传递数据的方式

1、父组件向子组件传递数据
// 1、Vue是单向数据流

// 父组件向子组件传递数据
<son1 :value="mny"/>
// 子组件接收
props:{
    value:{
        type:Number,
        default:1
    }
}
2、子组件向父组件传递数据
// 子组件向父组件传递数据,父组件将自己的方法传递给子组件
// 传递原理:组件解析时会将@input="change"解析成 {input: chagne}
// 这种对象形式传递到子组件中,子组件再调用 this.$on()方法,将传
// 递过来的{input: change} 绑定到自己身上,是给子组件绑定方法,然后
// 再通过 this.$emit()触发

<son1 :value="mny" @update="change"/>
this.$emit('input', 200)
3、父子组件相互传递同一数据的两种语法糖
// 父子组件相互传递数据的第一种语法糖
<son1 :value.sync="mny" />
就等于
<son1 :value="mny" @update:value="change"/>
this.$emit('update:val', 200) // 必须用update: [传递过来的值] 触发
// :value.sync="mny" 这种语法在解析时,会解析成,传递了一个属性value[可以自定义]
// 又传递了一个方法,默认是 update:value 

// 父子组件相互传递数据的第二种语法糖
<son1 v-model="mny" />
等同于
<son1 :value="mny" @input="mny => this.mny = mny"/>
this.$emit('input', 200);
// v-model="mny" 在解析的时候会解析成:向子组件传递了一个value的属性
// 和input方法

// 使用 .sync 和 v-model 的唯一区别在于,使用 .sync可以修改传递的属性
// 名称,v-model传递的属性必须就是value

4、多层数据传递

// 孙子级组件修改爷爷级组件数据

// 爷爷级组件向父级组件传递数据和给子组件绑定方法
<son1 v-model="mny" />
// 儿子组件触发$on()方法给自己绑定的方法
this.$emit('update:val', 200)
// 孙子组件触发儿子组件的方法,修改爷爷组件的数据
this.$parent.$emit('input', 1000)

// 基于多层数据传递封装的两个方法
Vue.prototype.$dispatch = function (eventName, value) {
    let parent = this.$parent;
    while(parent) {
        parent.$emit(eventName, value);
        parent = parent.$parent;
    }
  }
  
  Vue.prototype.$broadcast = function (eventName, value) {
    const broadcast = (children) => {
      children.forEach(child => {
         child.$emit(eventName, value);
         if(child.$children) {
            broadcast(child.$children);
         }
      })
    }
    broadcast(this.$children)
  }
// 注意:$emit()触发的只能是通过组件绑定的事件,也就是$on()绑定的
// 通过methods绑定的是无法触发的

5、通过 attrs 和listeners 获取父级传递过来的属性和方法\

1、$attrs
1、作用:$attrs 存储的是父级组件传递过来的所有属性,以键值对的形式
存在默认传递,而且这些传递过来的属性,会显示在当前组件的最外层DOM节
点上

<son2 name="jack" sex="meal" :mny="mny"/>
$attrs => { "name": "jack", "sex": "meal", "mny": 100 }

2、如果我们不想让传递的属性显示在DOM节点上,可以给当前组件添加属性:
inheritAttrs: false 

3、我们通过$attrs获取属性时,不需要再通过props去注册接收,但是可以去
接收

3、如果我们想将当前组件的 $attrs 继续向下传递,我们可以使用一个语
法糖 
<Grandson2 v-bind="$attrs"/>
或者
<Grandson2 v-bind="{name:$attrs.name, sex:$attrs.sex}"/>
或者
<Grandson2 v-bind="{name:1, sex:2}"/> // 传递其他属性
这样就可以将父级传递过来的属性原封不动的传递给自己的儿子,必须使用 v-bind
没有简写了;
2、$listeners
1、作用:$listeners存储的是父级传递过来的所有方法,也是以键值对的形式存在
$listeners => {son: ƒ}

<son2 name="jack" sex="meal" :mny="mny" @son="son"/>
$listeners.son() // 调用

2、继续向下传递:
<Grandson2 v-bind="$attrs" v-on="$listeners"/>

6、通过 provide 和 inject 提供和注入数据

1、provide
1、作用:provide可以将当前组件的数据暴露出去,供儿子级组件注入使用
provide() {
  return {'xixi': this} // 键可以随意,this就是当前组件
},
2、inject
inject:[
  'xixi' // 必须和父级组件provide的键名相同
],

// 儿子级组件注入父级组件数据后使用方式:
this.xixi.父级数据或者方法

7、通过 ref 获取子组件中的方法并调用

1、ref的用法:用在DOM上是获取DOM元素,用在组件上可以获取组件实例
<son2 name="jack" sex="meal" :mny="mny" @son="son" ref="son2"/>
this.$refs可以以获取到son2这个组件实例,自然就能够获取到son2中的
方法和属性; 

8、eventBus

Vue.prototype.$bus = new Vue(); // Vue实例上有 $on 和 $emit 方法

// 在任意组件中通过$on() 绑定方法
this.$bus.$on('gs2', function () {
  alert('eventBus')
})

// 任意组件中通过 $emit() 触发方法
this.$bus.$emit('gs2')

上一篇 下一篇

猜你喜欢

热点阅读