vue组件通信

vue组件通信

一、props

  • 适用场景:父子组件通讯

1、父组件,给子组件【ChildA】传递数据

<child-a :msg="msg"></child-a>

2、子组件,props接收数据

//props有两种写法
//1、数组形式
props:['msg']
//2、对象形式
props:{
    msg:{
        type:String,
            default:''
    }
},
props: {
    goods: {
        type: Array, 
        default(){ //default可以函数
            return []
        }
    }
}

二、$emit

  • 适用场景:子组件给父组件传递数据

1、子组件【ChildA】$emit发射事件goodsClick,传递数据item

//告诉父组件点击了那个商品
this.$emit('goodsClick',item);

2、父组件监听子组件【ChildA】发射的goodsClick事件,用handleGoods进行处理

<ChildA :goods="goodsList" @goodsClick="handleGoods"/>
handleGoods(item) {
    //操作子组件传过来的数据
},

自定义事件,需要$emit()$on()

  • $emit('自定义事件名',要传送的数据)--发送事件

  • $on('事件名',callback)--监听事件

  • 有点蠢的注释:在不同组件中this.$emit(),和this.$on(),this的组件实例对象是不一样的。所以不能this.$on()监听不到this.$emit发射的事件。同组件中可以。---->(事件源要相同)

三、全局事件总线$bus

  • 适用场景:万能,缺点不方便维护

1、在mian.js 中配置全局事件总线,挂载到Vue原型上

new Vue({
  render: h => h(App),
  beforeCreate(){
    Vue.prototype.$bus=this;//this=>VM
 },
}).$mount('#app')	

//其实就是: Vue.prototype.$bus=new Vue();

2、发送事件

  • this.$bus.$emit('自定义事件名',要传送的数据)
//通知兄弟组件,当前索引值是为几..送出事件
this.$bus.$emit('getIndex', this.currenyIndex);

3、监听事件

  • this.$bus.$on('事件名',callback)
//组件在什么周期挂载的时候,监听这个组件
mounted() {
    //通过全局事件总线,获取兄弟组件传递过来的索引值
    this.$bus.$on('getIndex', (index) => {
        //修改当前响应式数据
        this.currentIndex = index
    })
},

4、移除事件监听者

 this.$bus.$off('addClick');

四、Vuex

  • 适用场景:万能

[vuex]

五、插槽

  • 适用场景:父子组件通信(一般结构)
  • 默认插槽、具名插槽、作用域插槽

[插槽]

六、pubsub.js 发布订阅

  • 适用场景:万能

七、$attrs/$listener

  • 都是组件实例自身的属性
  • $attrs:可以获取到父组件传递过来的props数据。
    • 如果子组件已经通过props接收的属性,在$attrs属性当中是获取不到的。
  • $listeners:它可以获取到父组件给子组件传递的自定义事件。
<!--父组件-->
<div>
    <h1>二次封装element自定义按钮</h1>
    <EleBtn type="success" icon="el-icon-delete" size="minni" title="删除按钮" txt="删除" @click="handler"/>
</div>
<!--子组件-->
<div>
    <a :title="title">
        <!-- 不能使用语法糖 -->
        <el-button v-bind="$attrs" v-on="$listeners">{{txt}}</el-button>
    </a>
</div>
//子组件可打印查看值
mounted() {
    console.log(this.$attrs);//{type: 'success', icon: 'el-icon-delete', size: 'minni'}
    console.log(this.$listeners);//{click: ƒ}
}

八、$children/$refs

this.$children

  • 组件实例的属性,可以获取到当前组件的全部子组件【数组】。一般不通过这样拿。
console.log(this.$children);//返回所有的子组件对象的集合
console.log(this.$children[0]);
console.log(this.$children[0].money);
this.$children.forEach(item=>{
    item.money-=200;
})

this.$refs

  • 可以获取到真实的DOM节点,也可以获取到某一个子组件标签,操作子组件的数据和方法,
  • 组件对象类型,默认是个空的对象。常用。
  • 要在组件上加 ref="名字"。
<childA ref="childA"/>
console.log(this.$refs.childA);//获取属性值为ref="childA"的组件对象
console.log(this.$refs.childA.money);

九、$parent/$root

this.$parent

  • 组件实例的属性,可以获取到当前子组件的父组件,进而可以操作父组件的数据与方法。
  • 不建议使用,一个子组件可以被多个组件调用。一个父组件里有name这个属性,另一个父组件中可能没有。
console.log(this.$parent);
console.log(this.$parent.name);

this.$root

  • 访问根组件,也很少用。
  • vue实例里面东西很少,基本什么东西都没有
console.log(this.$root);
console.log(this.$root.name);//?手脚架中,App.vue根组件中定义了name,但是访问不到。
posted @ 2021-10-07 12:56  黄哈哈。  阅读(33)  评论(0编辑  收藏  举报