vue3 子组件可以修改props的属性值吗? 可以修改

1.概要

最近做项目的时候,遇到个问题,父组件直接修改子组件的data数据.于是在思考子组件是否可以修改父组件?
答案:可以的,不区分数据类型

2.父调子

//子组件
let items = reactive({
  select: [
    {
      key: 1,
      value: "",
      id: 1, // 必须存在,否则不可拖拽
    },
  ],
});
const getItems = () => {
  return items;
};

const resetItems = () => {
  items.select = [
    {
      key: 1,
      value: "",
      id: 1, // 必须存在,否则不可拖拽
    },
  ];
};

defineExpose({
  getItems,
  resetItems,
  items
});
//父组件 可以通脱refs调用,也可以直接赋值 xAxisFieldRef.value.items.select
xAxisFieldRef.value.getItems.select = data
.filter((x) => x.selectType === 1)
.map((x, index) => {
  return {
    key: index + 1,
    value: x.fieldName,
    id: index + 1,
  };
});

3.子调父

// 父组件
  <props-test
    v-model="model"
    :name="refName"
    :user="retUser"
    :attrs1="retUser"
  ></props-test>
  父组件基础类型{{ model }} 父组件引用类型{{ retUser }}
setup() {
   const state = {
     title: "vue3.0 demo",
   };
   const model = ref("aa");
   const refName = ref(0);
   const retUser = reactive({
     name: "gg",
   });
   return { state, model, refName, retUser };
 },
//子组件
<template>
  <div>
    <button @click="submit">测试基础类型 {{ props.modelValue }}</button>
    <button @click="direct">测试引用类型 {{ props.user }}</button>
  </div>
</template>

<script>
import { defineComponent } from "vue";

export default defineComponent({
  name: "propsTest",
  props: {
    modelValue: String,
    name: String,
    user: Object,
    info: Object,
  },
  emits: ["update:modelValue"],
  setup(props, context) {
    console.log("props-text", props);
    console.log("props-ctx", context);

    // 使用 emit 修改
    const submit = () => {
      //   context.emit("update:modelValue", new Date()); // 基础类型需要使用 emit 来修改
      props.modelValue = new Date(); // 直接手动修改无效
    };

    // 使用 proxy 修改
    const user = props.user; // 可以直接获取,不需要使用 toRef
    const direct = () => {
      user.name = new Date();
    };
    return {
      submit,
      direct,
      props,
    };
  },
});
</script>

4.本质

  • 基本数据类型:副本,不会影响数据的修改
    如何修改?
    context.emit("update:modelValue", new Date()); // 基础类型需要使用 emit 来修改
  • 引用数据类型:地址,会影响数据的修改
    如何修改?
    // 使用 proxy 修改
    const user = props.user; // 可以直接获取,不需要使用 toRef
    const direct = () => {
      user.name = new Date();
    };

5.总结

  • vue是单向数据流,父子组件却可以互相修改,官方不建议子组件修改props属性
  • props属性最终来源于父组件的data属性
  • 本质:区分js类型的差异
  • 基本类型需要用emit触发修改
  • 引用类型可以通过reactive直接修改
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐