vue3中常见的几种组件通信,你都知道吗?看一看下面的vue3组件通信写法,看看它和vue2中的组件通信有什么不同
Vue3中常见的七种组件通信
- props
- emit
- v-model
- refs
- provide/inject
- mitt
- vuex/Pinia
vue3的组件使用写法
1. props
props用来 父组件 -> 子组件传值
// Parent.vue
<template>
<ChildVue :list="list"></ChildVue> //将父组件的list数组传给子组件
</template>
<script setup>
const list =ref(['JavaScript','HTML','CSS'])
const value = ref('')
const handleAdd =() =>{
list.value.push(value.value)
value.value = ''
}
</script>
// Child.vue
<ul class="list-group">
//拿父组件的数组进行循环渲染
<li class="list-item" v-for="(item,index) in props.list" :key="index" >
{{item}}
</li>
</ul>
<script setup >
import { defineProps } from 'vue'; //专门用来解析父组件传递的数据
const props = defineProps({
list:{
type:Array,
default: () =>[]
}
})
</script>
vue3用setup 要 import { defineProps } from 'vue';
const props = defineProps () 才能使用props
2. emit
emit用来子组件 -> 父组件 传值
// Parent.vue
<template>
<div>
<!-- 子组件 -->
<ChildVue @add = 'childValue'></ChildVue> //add 就是子组件抛出的事件名
<!-- 父组件 -->
<div class="child">
<ul class="list-group">
<li class="list-item" v-for="(item, index) in list" :key="index">
{{ item }}
</li>
</ul>
</div>
</div>
</template>
// Child.vue
<template>
<div class="wrap">
<input type="text" class="form-control" v-model="value" />
<button class="btn" type="button" @click="handleAdd">添加</button>
</div>
</template>
<script setup>
import { ref,defineEmits } from "@vue/reactivity"
const emit = defineEmits() //定义一个事件名称
const value = ref('')
const handleAdd =() =>{
// this.$emit('add',value.value) vue2写法
emit('add',value.value) // vue3写法
value.value = ''
}
</script>
①:vue2 中用法是 在子组件 点击事件里面用 this.$emit('事件名',this.数据) 发散出去
②:vue3中用法是 import { defineEmits } from "@vue/reactivity"
const emit = defineEmits() 就可以用emit f方法了,其他和vue2 用法一样
3. v-model
v-model 用来子组件 -> 父组件 传值
// Parent.vue
<template>
<div>
<!-- 子组件 -->
<ChildVue v-model:list="list"></ChildVue> // v-model 双向绑定
</div>
</template>
<script setup>
import { ref } from 'vue';
import ChildVue from '../vmodel/Childs.vue';
const list =ref(['JavaScript','HTML','CSS'])
</script>
// Child.vue
<template>
<div class="wrap">
<input type="text" class="form-control" v-model="value" />
<button class="btn" type="button" @click="handleAdd">添加</button> //点击传值
</div>
</template>
<script setup>
import { ref,defineEmits,defineProps } from "@vue/reactivity"
const emit = defineEmits(['update:list']) //定义一个事件名称 'update:list' 固定写法
const props = defineProps({ // list需要用props接收
list:{
type:Array,
default:() =>[]
}
})
const value = ref('')
const handleAdd =() =>{
const arr = props.list
arr.push(value.value) //将要输入的值push进数组
emit('update:list',arr) // vue3写法 更新父组件list的值并传给父组件
value.value = ''
}
</script>
父组件中在子组件上v-model双向绑定
子组件中,用props接受,用emit 发散 并返回更新好的数据给父组件。 update:*是Vue中的固定写法,*表示props中的某个属性名。
4.refs
refs 用来子组件 -> 父组件传值
// Parent.vue
<template>
<div>
<!-- 子组件 -->
<ChildVue ref="childRefs"></ChildVue> //父组件na
</div>
</template>
// Child.vue
<template>
<div class="wrap">
<input type="text" class="form-control" v-model="value" />
<button class="btn" type="button" @click="handleAdd">添加</button>
</div>
</template>
<script setup>
import { ref,defineExpose } from "@vue/reactivity"
const list =ref(['JavaScript','HTML','CSS'])
const value = ref('')
const handleAdd =() =>{
list.value.push(value.value) //将要添加的值push进数组
value.value = ''
}
defineExpose({list}) // 抛出这个list
</script>
子组件中 script setup 写法会导致整个组件实例无法暴露出来,要用 defineExpose() 暴露出传给父组件的值。
5.provide/inject
provide/inject 用来父组件-> 子组件 传值
// Parent.vue
<template>
<div>
<ListVue ></ListVue>
</div>
</template>
<script setup>
const list =ref(['JavaScript','HTML','CSS'])
//向子组件 传递数据
provide('list',list.value)
const handleAdd =() =>{
list.value.push(value.value)
value.value = ''
}
</script>
//Child.vue
<template>
<li class="list-item" v-for="(item,index) in list" :key="index" >
{{item}}
</li>
</template>
<script setup >
import { inject } from 'vue'; //专门用来解析父组件传递的数据
const list = inject('list')
</script>
provide:可以让我们指定想要提供给后代组件的数据或
inject:在任何后代组件中接收想要添加在这个组件上的数据,不管组件嵌套多深都可以直接拿来用
6.mitt
mitt可以用来 子组件 <-> 父组件 互通数据,下面这个例子用来 子组件 -> 父组件 传值
//Parrnt.vue
<template>
<div>
<!-- 子组件 -->
<ChildVue @add = 'childValue'></ChildVue>
</div>
</template>
<script setup>
import emitter from './mitt' //引入mitt.js
const list =ref(['JavaScript','HTML','CSS'])
emitter.on('add',(val)=>{ // emitter.on用来接收数据
// console.log(val);
list.value.push(val)
})
</script>
// Child.vue
<template>
<div class="wrap">
<input type="text" class="form-control" v-model="value" />
<button class="btn" type="button" @click="handleAdd">添加</button>
</div>
</template>
<script setup>
import { ref } from "@vue/reactivity"
import emitter from './mitt' //引入 mitt.js
const handleAdd =() =>{
emitter.emit('add',value.value) // emitter.emit 抛出事件
value.value = ''
}
</script>
vue2当中使用EventBus(事件总线)实现组件通信,vue3中使用 mitt.js 或者 tiny-emitter.js
mitt用法: 先定义一个mitt.js 在里面引入 mitt 抛出mitt() 的调用 ,为了让父子组件引入的为同一份mitt.js。
在父子组件中 引入这份js,然后用emitter.emit('事件名',数据) 抛出, emitter.on('事件名',(val) => { }) 接收
7. vuex/Pinia
vuex 的用法比较简单。在store.js仓库里面存数据。然后父子组件引入store.js。对数据进行操作。可以把它看成第三方。Pinia和vuex操作类似。
新手上路,如有不对的或者遗漏的,欢迎指正,你的一赞一评都是我前行最大的动力,感谢