组件之间的传值在vue 项目中是一个非常普遍的现象,在通信的时候,一般注意一下两个原则:
1.不要在子组件中直接修改父组件的状态数据
2.数据和处理数据的函数应该在同一个模块内
vue中组件通信常用的方式:
props属性
自定义事件
消息订阅与发布
vuex
1.组件通信方式一:props属性
声明方式:
(1)只指明名称
(2)指定名称和类型
(3)指定名称/类型/必要性/默认值
props可以接收数组,也可以接收对象,可以通过属性的方式直接写在子组件上进行传递。例如:
//父组件
<propsComponent name="zs" :age=23/>
//子组件
props:["name","age"]
此时没有声明明确的类型,可以规定类型,则子组件中这样写:
props:{
name:String
age:Number
}
注意点:
vue使用props属性传值通信时,除了字符串可以直接传值外,其他类型,如数字、布尔型、对象等都应该动态绑定,否则会报警告或者错误。
另外,父组件在调用子组件的时候,在子组件中触发某个按钮,请求父组件中的某个方法,可以传函数。
例如:
//子组件
<button @click="getMethods">调用方法</button>
props:{
getMethods: Function
}
//然后方法在父组件中定义
//父组件
<propsComponent name="zs" :age=23 :per="p" :func="getMethods"/>
methods:{
getMethods(){
...
}
}
使用注意:
1.此方式适用于父组件向子组件传递数据
2.所有标签属性都会成为组件对象的属性,模板页面可以直接使用
存在缺陷:
1.如果需要向非子后代传递数据必须多层逐层传递
2.兄弟组件间也不能直接props通信,必须借助父组件才可以
2.组件通信方式二:自定义事件
操作:
在子组件中绑定事件监听
父组件中触发事件
指定名称/类型/必要性/默认值
例如:
//子组件
<button @click="btnClick"/>
methods:{
btnClick(){
this.$emit("btnClick",{name:"zs",age:23});
}
}
//父组件
<CostomEvents @btnClick="deleteP" />
<p ref="word" class="word"> .....................</p>
methods:{
deleteP(args){
this.$ref.word.remove();
}
}
//或者在父组件中可以这样写
<CostomEvents ref="custom" />
mounted(){
this.$ref.custom.$on("btnClick",this.deleteP);
}
使用注意:
1.此种方式只适用于子组件向父组件传递数据
2.隔代组件或者兄弟组件间通信此种方式不合适
3.组件通信方式三:消息订阅
使用工具库:PubSubJS
npm install pubsub-js --save
订阅:import PubSub from 'pubsub-js'
PubSub.subscribe('delete',function(msg,data){})
发布:import PubSub from 'pubsub-js'
PubSub.publish('delete',data);
4.组件通信方式四:slot插槽
使用方式:1.先在子组件template中写好插槽,并用name唯一标识插槽。
如:
<template>
<div calss="todo_footer">
<label>
<slot name="checkAll"></slot>
</label>
<sapn>
<slot name="count"></slot>
</sapn>
<slot name="delete"></slot>
</div>
</template>
2.父组件在子组件中调用需要的插槽,不需要的就不调用。
如:
<todo_footer>
<input type="checkbox" v-model="isAllCheck" slot="checkAll"/>
<botton slot="delete" calss="btn" v-show="isShow"/>XXX</button>
</todo_footer>
注意点:
所有与插槽有关的功能,都应该放在调用插槽结构的页面,依次,与v-show相关的isShow函数应该放在父组件中实现。