Vue3组件间通信知识整理——父组件向子组件传参

赶时间的帅比可以跳过此段!项目重构差不多了,觉得有必要花几天事件整理一下重构过程中遇到的各种各样的问题及解决方案。我认为各种问题的出现的背后都是需求的驱使,所以我在文章书写的过程中,相对简单的以案例演示叙述,而相对特殊典型的尽量放出场景、聊需求,增加代入感的方式来叙述Vue3组件间通信的方式。

先准备一个清清爽爽的文件。结构目录如下⬇

请添加图片描述

项目重构时遇到的组件间通信有:

  1. 父组件向子组件传参
  2. 子组件向父组件传参
  3. 兄弟组件间通信
  4. 父组件调用子组件方法

父组件向子组件传参

组件化开发,父组件向子组件传参的情景是极为常见、普遍的。

基本

// 父组件传出
<script setup>
import { reactive, ref } from 'vue'
import childrenTest_oneVue from "./conponents/childrenTest_one.vue";

const name = "小明"
const age = ref(18)
const brother = [
  '小红','小芳','小白'
]
const info = reactive({
  gender: '男',
  brithday: '2000/01/01'
})
</script>

<template>
  <childrenTest_oneVue :name="name" :age="age" :brother="brother" :info="info"/>
</template>

// -------------------分界线------------------------

// 子组件接收
<script setup>
const props = defineProps({
  name: {
    type: String
  },
  age: {
    type: Number
  },
  info: {
    type: Object
  },
  brother: {
    type: Array
  }
})

props.name = '小东'
props.age = 19
props.info.gender = '女'
props.brother[0] = '小猪'

console.log(typeof props.name)
console.log(props.age)
console.log(props.info)
console.log(props.brother)
</script>

<template>
  <span>姓名: {{ name }}</span>
  <br/><br/>
  <span>年龄: {{ age }}</span>
  <br/><br/>
  <span>基本信息: {{ info.gender }}  {{ info.brithday }}</span>
  <br/><br/>
  <div>
    <span>兄弟姐妹: </span>
    <span v-for="(item,index) in brother" :key="index">{{ item }}&nbsp;</span>
  </div>
</template>

浏览器及操作台输出⬇

请添加图片描述

浏览器渲染和操作台打印如上,可以得出以下几点结论:

  1. 父组件使用ref响应式处理 js 基础数据类型,使用reactive响应式处理 js 引用数据类型,在传输之后在子组件原始数据类型的响应式会丢失,而引用数据类型的响应式会保留,最终都不影响在html文档中使用。
  2. 父组件向子组件传参,原则上子组件不能直接去修改props的数据(编译器中书写类似的修改代码eslint会报错,但不影响运行),原始数据类型直接修改会出现只读警告且修改失效,引用数据类型直接修改不会出现警告且修改成功。这跟 js 这两种基础数据类型的存储方式有关,原始数据类型直接把值存储在内存地址当中,引用数据类型在内存地址中存储的是该类型数据的“指针”,也就是说该“指针”只读,而不是里面的值只读,有const那味了。

总结

Vue3的setup语法糖父组件向子组件传参就如上述。…

文章有问题之处还望评论斧正!

更多其他组件间通信文章链接放在下方⬇

Vue3组件间通信知识整理——子组件向父组件传参
Vue3组件间通信知识整理——兄弟组件之间通信
Vue3组件间通信知识整理——父组件调用子组件方法

### Vue子组件父组件传递参数的深度监听 在 Vue.js 中,当父组件通过 `props` 向子组件传递复杂的数据结构(如对象或数组),默认情况下,`watch` 只会检测到顶层属性的变化。为了实现更深层次的响应式更新,可以采用几种不同的方法来确保子组件能够及时感知并处理这些变化。 #### 方法一:使用 `deep` 属性进行深层监听 可以在 `watch` 选项里设置 `{ deep: true }` 来开启深一层级的对象监控: ```javascript // 子组件内部 export default { props: [&#39;parentData&#39;], data() { return {}; }, watch: { parentData: { handler(newValue, oldValue) { console.log(&#39;Parent Data Changed:&#39;, newValue); }, immediate: true, deep: true // 开启深度监听 } } } ``` 这种方法适用于简单的场景,在不需要频繁触发的情况下效果良好[^1]。 #### 方法二:利用计算属性与缓存机制优化性能 对于大型应用来说,过度依赖 `deep watcher` 可能会影响性能。此时可以选择只监视特定路径下的值变动,并结合计算属性来进行逻辑分离: ```javascript computed: { specificPropertyOfParentData() { const propValue = this.parentData && this.parentData.specificKey; doSomethingWith(propValue); // 执行某些操作 return propValue || defaultValue; } }, watch: { specificPropertyOfParentData(newVal) { handleSpecificChange(newVal); } } ``` 此方式不仅提高了代码可读性和维护性,还减少了不必要的重新渲染次数[^2]。 #### 方法三:借助 Vuex 或者事件总线管理状态共享 如果项目规模较大且涉及多个层级之间的通信,则推荐引入全局的状态管理模式——Vuex;或者是创建一个独立于任何单个组件之外的事件中心(Event Bus),用于跨组件间的消息传递和服务调用。 以上三种策略可以根据实际需求灵活选用,以达到最佳实践目的的同时保持良好的用户体验和开发效率。 ```html <!-- 父组件 --> <template> <child-component :complex-object="localObject"></child-component> </template> <script> import ChildComponent from &#39;./ChildComponent.vue&#39;; export default { components: { ChildComponent }, data() { return { localObject: {} }; }, created() { fetch(&#39;/api/data&#39;) .then(response => response.json()) .then(data => (this.localObject.deeplyNestedProp = data)); } }; </script> ``` ```html <!-- 子组件 --> <template> <!-- 使用来自父组件的数据 --> </template> <script> export default { props: [&#39;complexObject&#39;], mounted() { // 初始化时执行的操作... }, methods: {}, computed: {}, watch: { complexObject: { handler(value) { console.log(&#39;Complex Object Updated&#39;, value); }, deep: true } } }; </script> ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值