vue3在父组件中直接传递props响应式对象给子组件,为什么子组件可以修改值?

<template>
  <div ref="root" class="homse">
    <!-- {{ refTreeData }} -->
    <recursiveCom :tree-data="refTreeData"></recursiveCom>
  </div>
</template>

<script setup lang="ts">
import type { nodeType } from './type'
import { ref, reactive } from 'vue'
// 测试 tree 型组件
import recursiveCom from './recursiveCom.vue'
let treeDataTest = [
  {
    title: '节点名称',
    id: '1',
    status: '未开始',
    start_time: '2023.08.10',
    end_time: '2023.08.16',
    falg: true,
    show: true,
    children: [
      {
        title: '子节点名称',
        id: '1 - 1',
        status: '进行中',
        start_time: '2023.08.10',
        end_time: '2023.08.16',
        show: true,
        children: [
          {
            title: '子节点名称',
            id: '1 - 1 - 1',
            status: '进行中',
            start_time: '2023.08.10',
            end_time: '2023.08.16'
          },
          {
            title: '二子节点名称',
            id: '1 - 2 - 2',
            status: '已完成',
            start_time: '2023.08.10',
            end_time: '2023.08.16'
          }
        ]
      },
      {
        title: '二子节点名称',
        id: '1 - 2',
        status: '已完成',
        start_time: '2023.08.10',
        end_time: '2023.08.16'
      }
    ]
  },
  {
    title: '节点名称',
    id: '2',
    status: '未开始',
    start_time: '2023.08.10',
    end_time: '2023.08.16',
    falg: true,
    show: true,
    children: [
      {
        title: '子节点名称',
        id: '2 - 1',
        status: '进行中',
        start_time: '2023.08.10',
        end_time: '2023.08.16'
      },
      {
        title: '二子节点名称',
        id: '2 - 2',
        status: '已完成',
        start_time: '2023.08.10',
        end_time: '2023.08.16'
      }
    ]
  }
]

let refTreeData = ref<nodeType[]>(treeDataTest)
</script>
<style scoped></style>

子组件

<template>
  <div style="border: 1px solid #ccc; margin: 10px">
    <div v-for="node in treeData" :key="node.id">
      <span
        v-if="node.children"
        class="icon"
        :class="node.show ? 'packup' : 'openup'"
        @click="expansion(node)"
        >🔺</span
      >
      <div class="continer">{{ node.id }}{{ node.title }} {{ node.status }}</div>
      {{ node.show }}
      <template v-if="node.show">
        <recursive-node v-if="node.children" :tree-data="node.children" />
      </template>
    </div>
  </div>
</template>

<script setup lang="ts">
import type { nodeType } from './type'
import recursiveNode from './recursiveCom.vue'
defineProps<{
  treeData: nodeType[]
}>()
let expansion = (node: nodeType) => {
  node.show = !node.show
}
</script>

<style scoped lang="less">
.packup {
  transform: rotate(180deg);
}
.openup {
  transform: rotate(90deg);
}
.icon {
  display: inline-block;
  cursor: pointer;
}
.continer {
  display: inline-block;
}
</style>

在expansion函数中可以直接修改父组件的值,vue也不会报警告,这是被允许的吗?为什么可以正常修改

阅读 3.6k
1 个回答

https://cn.vuejs.org/guide/components/props.html#one-way-data...

对象或数组作为 props 被传入时,虽然子组件无法更改 props 绑定,但仍然可以更改对象或数组内部的值。这是因为 JavaScript 的对象和数组是按引用传递,而对 Vue 来说,禁止这样的改动,虽然可能生效,但有很大的性能损耗,比较得不偿失。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题