首页
Preview

Vue3 避免直接引用对象/数组 props

props

在Vue3中,当将对象或数组props作为子组件传递时,无法更改对象或数组本身,但可以更改对象或数组的嵌套属性。

当传递单个值作为 props 时

如果将单个值作为 props 传递,则更改子组件中的 props 值将不会反映父组件中的更改。这是因为 props 是单值的,因此子组件中的更改将被视为与局部变量的更改相同。

<script setup lang="ts">
const props = defineProps(['hoge'])

// 警告:props是只读
props.hoge = 'bar'
</script>

当传递对象或数组作为 props 时

如果将对象或数组作为 props 传递,则子组件无法直接修改父组件传递的对象或数组的属性。但是,如果对象或数组属性发生更改,Vue3 将检测到更改并更新父组件的数据。

<script setup lang="ts">
interface MyObject {
  name: string;
  age: number;
  hobbies: string[];
}

const props = defineProps({
  myObject: {
    type: Object as () => MyObject,
    required: true,
  },
});

const changeHobbies = () => {
  // 可以更改通过 props 从父级接收到的 myObject 的属性
  props.myObject.hobbies.push('baking');
};
</script>

<template>
  <div>
    <p>{{ myObject.name }}</p>
    <p>{{ myObject.age }}</p>
    <ul>
      <li v-for="hobby in myObject.hobbies" :key="hobby">{{ hobby }}</li>
    </ul>
    <button @click="changeHobbies">Change Hobbies</button>
  </div>
</template>

可能出现的问题

这些规范允许子组件影响父组件的状态...... 下面的官方文档还指出,最好的做法是避免此类更改,除非设计在父子之间紧密耦合,因为这使得以后很难确定数据流。 https://cn.vuejs.org/guide/components/props.html

如何将对象/数组作为 props 传递以避免意外的数据流

可以举出一个最佳实践的例子:

<script setup lang="ts">
import { defineProps, ref, Ref } from 'vue';

interface HogeObject {
  name: string;
  age: number;
}

const props = defineProps({
  arrHoge: {
    type: Array as () => Array<number | string>,
    required: true,
  },
  objHoge: {
    type: Object as () => HogeObject,
    required: true,
  },
});

//使用扩展语法扩展为新数组
const arrHoge: Ref<Array<number | string>> = computed(() => [...props.arrHoge]);
const objHoge: Ref<HogeObject> = computed(() => ({ ...props.objHoge }));
</script>

<template>
  <div>
    <p>Array: {{ arrHoge }}</p>
    <p>Object: {{ objHoge }}</p>
  </div>
</template>

这段代码将arrHogeobjHoge定义为计算为新数组和新对象的值。这样,即使 props.arrHogeprops.objHoge 值发生变化,arrHogeobjHoge 也将始终引用新的数组和新的对象。

版权声明:本文内容由TeHub注册用户自发贡献,版权归原作者所有,TeHub社区不拥有其著作权,亦不承担相应法律责任。 如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

点赞(0)
收藏(0)
Hedy
大家好!我是一位前端开发工程师,拥有6年以上的前端开发经验。我熟练掌握HTML、CSS、JavaScript等语言,能够灵活运用各种前端框架,如Vue、React、Uniapp、Flutter等。我注重理论与实践相结合,能够为学员提供丰富的案例和实践项目,并以生动、易懂的语言为学员讲解前端开发的核心知识和技能。我不仅注重传授技能,更关注学员的职业发展,希望通过我的教学,帮助学员成为一名优秀的前端开发工程师。

评论(0)

添加评论