Vue系列十七:组件间通信

组件间通信
1、组件间通信基本原则:
(1)、不要在子组件中直接修改父组件的状态数据
(2)、数据在哪, 更新数据的行为(函数)就应该定义在哪
2、vue 组件间通信的五种方式:
(1)、props
(2)、自定义事件
(3)、消息订阅与发布
(4)、slot
(5)、vuex
组件间通信方式一:props
1、在父组件传递属性

	<List name='tom' :age='3' :set-name='setName'></List >

2、 在子组件内接收所有的属性
(1)、方式一: 只指定名称

	props:['name','age','setName']

(2)、方式二: 指定名称和类型

    props:{ 
    	name:String, 
    	age:Number, 
    	setNmae:Function 
    }

(3)、方式三: 指定名称、类型、必要性和默认值

    props:{ 
    	name:{type:String,required:true,default:xxx}, 
    }

注意:

  1. 此方式用于父组件向子组件传递数据
  2. 所有标签属性都会成为组件对象的属性, 模板页面可以直接引用
  3. 问题:
    a. 如果需要向非子后代传递数据必须多层逐层传递
    b. 兄弟组件间也不能直接 props 通信, 必须借助父组件才可以

案例:
在父组件App.vue中传递属性

	<Item :comment="comment" :deleteComment="deleteComment" :index="index"/>
    <List :comments="comments" :deleteComment="deleteComment"/>
    <Add :addComment="addComment"/>

在子组件List.vue中接收属性

    //声明接收属性:这个属性就会成为组件对象的属性
    props: ['comments','deleteComment'],//只是指定属性名

在子组件Item.vue中接收属性

	props: {//指定属性名和属性值的类型
        comment: Object,
        deleteComment: Function,
        index: Number
    }

在子组件Add.vue中接收属性

	props:{
        addComment:{//指定属性名、属性值的类型、必要性
        	type: Function,
        	required: true
        }
    }

组件间通信方式二:自定义事件
1、绑定事件监听
方式一: 通过 v-on 绑定

	@delete_todo="deleteTodo" 

方式二: 通过$on()

    this.$refs.xxx.$on('delete_todo',function(todo){ 
    	this.deleteTodo(todo) 
    })

2、 触发事件

	this.$emit(eventName,data)

注意:

  1. 此方式只用于子组件向父组件发送消息(数据)
  2. 问题:隔代组件或兄弟组件间通信此种方式不合适

案例:
在父组件App.vue中绑定事件监听

	<!--给TodoHeader标签对象绑定addTodo事件监听-->
	<TodoHeader @addTodo="addTodo"/>

在子组件TodoHeader.vue中触发事件

 	methods:{
        addItem(){
	        //触发自定义事件:addTodo
	        this.$emit('addTodo',todo)
      	}
    }

组件间通信方式三:消息订阅与发布
下载PubSubJS:npm install --save pubsub-js
1、订阅消息

	PubSub.subscribe('msg',function(msg,data){
	})

2、发布消息

	PubSub.publish('msg',data)

注意
 优点: 此方式可实现任意关系组件间通信(数据)

案例:
在父组件App.vue中订阅消息

	import PubSub from 'pubsub-js'

	mounted(){ 
	    //订阅消息
	    PubSub.subscribe('deleteTodo', (msg,index) =>{
	      this.deleteTodo(index)
	    })
	}

在子组件TodoItem.vue中发布消息

	import PubSub from 'pubsub-js'

	methods:{
	    deleteItem(){
	    const {todo,index} = this
	    if(window.confirm(`确认删除${todo.title}吗?`)){
	      //发布消息
	      PubSub.publish('deleteTodo',index)
	    }
	  }
	}

组件间通信方式四:slot
此方式用于父组件向子组件传递标签数据
1、子组件:Child.vue

    <template> 
	    <div>
		    <slot name="xxx">不确定的标签结构</slot> 
		    <div>组件确定的标签结构</div> 
		    <slot name="yyy">不确定的标签结构</slot> 
	    </div> 
    </template>

2、父组件:Parent.vue

    <child> 
	    <div slot="xxx">xxx对应的标签结构</div> 
	    <div slot="yyy">yyyy对应的标签结构</div> 
    </child>

主要用于某一标签被反复使用时,可以使用slot插槽

案例:
在父组件App.vue中定义slot插槽

	<todo-footer>
		<input type="checkbox" v-model="isAllCheck" slot="checkAll"/>
	    <span slot="count">已完成{{completeSize}} / 全部{{todos.length}}</span>
	    <button class="btn btn-danger" v-show="completeSize" @click="deleteCompleteTodos" slot="delete">清除已完成任务</button>
	</todo-footer>

在子组件TodoFooter.vue中使用slot插槽

	<slot name="checkAll"></slot>
    <slot name="count"></slot>
    <slot name="delete"></slot>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值