VUE3(四)、组件通信
1、props
作用:子组件之间的通信。
父传子:属性值的非函数。
子传父:属性值是函数。
父组件:
{{ childeData }} —————————————————————————————— import { ref } from \'vue\';import child from \'./childeIndex.vue\'const childeData=ref(\"\");const parentData=ref(\"parentData\");function getChildData(data:string){ childeData.value=data;}
子组件:
{{ parentData }} import { ref } from \'vue\'defineProps([\'parentData\',\'sendData\'])const data=ref(\'aaa\')
2、自定义事件
通过父组件定义函数,子组件调用父组件的函数来实现参数的传递。
父组件:
{{ childeData }} —————————————————————————————— import { ref } from \'vue\';import child from \'./childeIndex.vue\'const childeData=ref(\"\");function getChildData(data:string){ childeData.value=data;}
子组件:
子组件 import { ref } from \'vue\' let data=ref(\'我是子组件\') const emit = defineEmits([\'send-toy\']) function sendDat(){ emit(\'send-toy\',data) }
3、mitt
实现任意组件的通信。个人理解:在组件与组件之间提供了一个平台,都向这个平台发送、读取数据。
安装步骤:
- npm i mitt
- 新建文件utiles/emitter.ts
- 在需要的文件中引入emitter,进行绑定 事件,或调用事件。
- 在文件中进行解绑(unmounted中)
emitter.ts
import mitt from \'mitt\'const emitter=mitt()export default emitter
获取数据的文件
child2中的数据:{{ src }}
import { onUnmounted, ref } from \'vue\' import emitter from \'@/utils/emitter\' const src=ref(\'\') //监听事件 emitter.on(\'getData\',(data:string)=>{ src.value=data }) //在组件销毁时取消监听 onUnmounted(()=>{ emitter.off(\'getData\') })
发送数据的文件
child2的数据:{{ data }}
import { ref } from \'vue\' import emitter from \'@/utils/emitter\' const data = ref(\'222\') function getdata(){ emitter.emit(\'getData\',data) }
4、v-model
原理:实现双向绑定,通过传递props参数实现父传子,通过emit传递input或者点击事件实现子传父。
父组件:
<input type=\"text\" :value=\"str\" @input=\"str=($event.target).value\"/> import { ref } from \'vue\';import selfInput from \'./selfInput.vue\';let str = ref(\'\');
自定义组件(selfInput.vue):
import { ref,defineProps,defineEmits } from \'vue\';defineProps([\'modelValue\'])const emit = defineEmits([\'update:modelValue\'])
如果自定义自定义组件中的名称,可以实现多个组件的双向绑定。
父组件:
{{ str }} --------{{ pass }} import { ref } from \'vue\';import selfInput from \'./selfInput.vue\';let str = ref(\'\');let pass = ref(\'\');
子组件:
import { ref,defineProps,defineEmits } from \'vue\';defineProps([\'name\',\'pass\'])const emit = defineEmits([\'update:name\',\'update:pass\'])
5、$attrs
作用:适用于当前组件,向子组件通信(祖-->孙)。
当父组件给子组件传递参数,且子组件没有使用props进行接收时,所传递的参数存在attrs中。在子组件中使用$attrs就可以获取所有未被接收的数据。
父组件:
{{ a }}
{{ b }}
{{ c }}
import { ref } from \'vue\';import child from \'./chile.vue\';let a=ref(1);let b=ref(2);let c=ref(3);function changeA(value:number){ a.value=value;}
子组件:
{{ a }}
-------------------------------- import sun from \'./sun.vue\' defineProps([\'a\'])
孙组件:
{{ b }}
{{ c }}
const num=defineProps([\'b\',\'c\']); const emit=defineEmits([\'changeA\']); function changeAa(){ emit(\'changeA\',num.b); }
6、$refs、$parent
$refs:用于父组件修改子组件中的数据。获取所有子组件暴露的数据。
$parent:用于子组件修改父组件的数据。获取父组件所有暴露的数据。
以上的前提:使用defineExpose暴露数据。
父组件:
父组件数据
{{ a }}
-------------------------------- -------------------------------- import { ref } from \'vue\';import child1 from \'./childe1.vue\';import child2 from \'./childe2.vue\';let a=ref(1);function changeChildeA(refs:any){ refs.child1.b++; refs.child2.b++;}defineExpose({a})
子组件1:
子组件数据
a:{{ a }}
b:{{ b }}
import { ref } from \'vue\'let a=ref(1)let b=ref(1)function changeParent(parent:any){ parent.a++}//暴露defineExpose({ b})
子组件2:
子组件数据
a:{{ a }}
b:{{ b }}
import { ref } from \'vue\'let a=ref(1)let b=ref(1)//暴露defineExpose({ a, b})
7、provide、inject
作用:实现祖孙组件之间的数据传递。
传递数据:provide(“数据名称”,数据)。
接收数据:inject(“数据名称”,默认值)。
父组件:
父组件数据
{{ a }}
-------------------------------- import { ref,provide } from \'vue\';import child1 from \'./childe1.vue\';let a=ref(0);function changeA(value:number){ a.value+=value;}provide(\"parent\",{a:a,changeA})
子组件:
子组件数据
a:{{ a }}
import { ref,inject } from \'vue\'let {a,changeA} = inject(\'parent\',{a:ref(0),changeA:function(x:number){}})
8、插槽
作用:引入组件时可以给组件传递一些HTML元素。
默认插槽
父组件中引入子组件时,子组件标签内部的元素就是会传入slot的参数。
子组件中的slot就相当于占位符,给未来传进来的元素预留空位。
父组件:
父组件数据
1111111111 22 import child1 from \'./childe.vue\';
子组件:
{{ title }}
默认值 defineProps([\'title\'])
具名插槽
作用:可以指定元素插入的位置。
用法:在定义插槽位置时,使用name属性定义其名字。
在应用组件时,在其标签或Templet标签内部定义v-slot(或使用#+名字)属性。
父组件:
父组件数据
1111111111 22 import child1 from \'./childe.vue\';
子组件:
{{ title }}
默认值 -------------分隔符--------------------
默认值 defineProps([\'title\'])
作用域插槽
作用:当父组件需要子组件的数据。
用法:在定义slot标签时,使用props写法进行传递参数。
在父组件中使用v-slot拿到参数。
如果同时使用了具名插槽:v-slot:name=‘parms’
父组件:
父组件数据
- {{ item.name }}
import child1 from \'./childe.vue\';
子组件:
{{ title }}
默认值 import { reactive } from \'vue\'; defineProps([\'title\']) const game=reactive([ {id:1,name:\'a\'}, {id:2,name:\'b\'}, ]) const a=1;