学习了Vue3也有一段时间了,打算总结一下几种组件的通信方式。 既然学的是vue3,就听官方的,用了3,就不写2了。一律setup语法糖吧。
props
很简单的一种父子组件传参的方式,由父组件定义,通过v-bind绑定子组件,子组件通过defineProps接受参数,子组件只读且无法修改参数。
<!-- 父组件 -->
<template>
<div class="header">
<input type="text" v-model="newMsg">
<button @click="add">确定</button>
</div>
<Child :list="list" />
</template>
<script setup>
const newMsg = ref('')
const list = ref(['html', 'css'])
const add = () => {
list.value.push(newMsg.value)
}
</script>
<!-- 子组件 -->
const props = defineProps({
list: {
type: Array,
default: () => []
}
})
在上面例子中,父组件将list传递给子组件,子组件定义props使用,当然也可以直接list:Array,都可以。
那么问题来了,如果我将list放在子组件中,子组件接收父组件传来的新的list元素msg,如何去实时更新list呢?
- computed 如果你使用computed计算属性,那么你需要考虑到最开始的空字符串,还有返回的格式,是直接返回
return [...list.value, props.msg]呢?还是需要push一下再返回? - watch : 使用watch监听当然也是个不错的选择。
- 生命周期🪝onBeforeUpdate 它在组件即将进行更新前被调用,请注意,组件更新前,也就是说html中的元素,所以你需要用到它才行。
emit(发布)
emit函数需要从defineEmits辅助函数中获取。defineEmits用于定义组件可以触发哪些事件以及这些事件的有效负载类型。同时可以传递参数一起发布 父组件再定义函数获取该值。
//子组件定义一个名为addMsg的事件
const emits = defineEmits(['addMsg'])
const add =() =>{
emits('addMsg',newMsg.value) //发布订阅
}
//父组件订阅这个事件,并且通过handle方法处理,在handle中,通过list.value.push(e)更新。
<child @addMsg="handle"/>
v-model
用于在表单输入元素(如<input>, <textarea>, <select>等)和Vue实例的数据属性之间创建双向数据绑定。这意味着当用户在表单元素中输入数据时,相应的Vue实例的属性会自动更新,反之亦然。
- 对于
<input>元素,v-model实际上是v-bind:value和v-on:input的语法糖。它会监听input事件,以便在数据改变时更新数据属性。 - 对于
<textarea>元素,v-model同样绑定value和input事件。 - 对于
<select>元素,v-model会根据<option>的value属性来更新数据属性。 - 对于复选框和单选按钮,
v-model会绑定change事件,并且对于复选框组(使用<select multiple>或一组<input type="checkbox">),v-model期望一个数组来存储选中的值。
provide / inject
provide / inject 为依赖注入
provide:可以让我们指定想要提供给后代组件的数据或
inject:在任何后代组件中接收想要添加在这个组件上的数据,不管组件嵌套多深都可以直接拿来用
//父组件
<template>
<div class="header">
<input type="text" v-model="newMsg">
<button @click="add">确定</button>
</div>
<Child />
</template>
<script setup>
const add = () => {
list.value.push(newMsg.value)
newMsg.value = '' // 清空输入框
}
provide('list', list)
</script>
//子组件
<script setup>
import { ref, inject } from 'vue';
const list = inject('list')
</script>
Vuex/Pinia
这两种相比于其它的方式来说就更为便捷,但是如果你只是一个小的demo,那当我没说。 这里就不细讲了,需要我们自行去了解,传送门:Pinia/Vuex
- 选择 Vuex:如果你正在使用 Vue 2,或者你的项目已经基于 Vuex 并且需要支持 Vue 2 和 Vue 3 的多版本兼容性,那么继续使用 Vuex 可能是最合适的选择。
- 选择 Pinia:如果你使用的是 Vue 3,尤其是如果你的项目利用了组合式 API 的优势,那么 Pinia 将提供更现代、更简洁的状态管理方案。