简单数据类型不可直接修改,复杂可以修改

简单数据类型不可修改,复杂数据类型可以修改,简单数据类型存储在栈中,复杂数据类型栈中存放指针,堆中存放数据。

一.简单数据类型不可直接修改

<template>
  <div class="">
    <One :num="aa" />
  </div>
</template>

<script>
import One from "@/components/One.vue";
export default {
  components: {
    One,
  },
  data() {
    return {
      aa: 123,
    };
  },
  name: "",
  methods: {},
};
</script>

<style scoped></style>

<template>
  <div class="">
    <h1>{
   
   { num }}</h1>
    <button @click="fn">点击修改  </button>
  </div>
</template>

<script>
export default {
  props: {
    num: {
      type: Number,
      default: 10,
    },
  },
  name: "",
  methods: {
    fn() {
      this.num = 321;
    },
  },
};
</script>

<style scoped></style>

点击按钮之后:

 正确的修改方式:

<template>
  <div class="">
    <h1>{
   
   { cc }}</h1>
    <button @click="fn">点击修改</button>
  </div>
</template>

<script>
export default {
  props: {
    num: {
      type: Number,
      default: 10,
    },
  },
  data() {
    return {
      cc: this.num,
    };
  },
  name: "",
  methods: {
    fn() {
      this.cc = 321;
    },
  },
};
</script>

<style scoped></style>

将它的值重新赋值给一个变量,然后在去修改这个变量,这样就与父组件不建立联系。

或者去通知父组件去修改,也就是子传父。

<template>
  <div class="">
    <One :num="aa" @input="show" />
  </div>
</template>

<script>
import One from "@/components/One.vue";
export default {
  components: {
    One,
  },
  data() {
    return {
      aa: 123,
    };
  },
  name: "",
  methods: {
    show(val) {
      this.aa = val;
    },
  },
};
</script>

<style scoped></style>
<template>
  <div class="">
    <h1>{
   
   { num }}</h1>
    <button @click="fn">点击修改</button>
  </div>
</template>

<script>
export default {
  props: {
    num: {
      type: Number,
      default: 10,
    },
  },
  data() {
    return {};
  },
  name: "",
  methods: {
    fn() {
      this.$emit("input", 321);
    },
  },
};
</script>

<style scoped></style>

        

二.复杂数据类型的传递

代码:

<template>
  <div class="">
    <h1>我是父组件的</h1>
    <div v-for="(item, index) in arr" :key="index">
      <div>{
   
   { item.name }}------{
   
   { item.age }}</div>
    </div>
    <One :num="arr" />
  </div>
</template>

<script>
import One from "@/components/One.vue";
export default {
  components: {
    One,
  },
  data() {
    return {
      arr: [
        {
          name: "张亮",
          age: 20,
        },
        {
          name: "李芳",
          age: 18,
        },
      ],
    };
  },
  name: "",
  methods: {},
};
</script>

<style scoped></style>
<template>
  <div class="">
    <div class="aa" />
    <h1>我是子组件的</h1>
    <div v-for="(item, index) in num" :key="index">
      <div>{
   
   { item.name }}-----{
   
   { item.age }}</div>
    </div>
    <button @click="fn">点击修改</button>
  </div>
</template>

<script>
export default {
  props: {
    num: {
      type: Array,
    },
  },
  data() {
    return {};
  },
  name: "",
  methods: {
    fn() {
      this.num[0].name = "这个年纪";
    },
  },
};
</script>

<style scoped>
.aa {
  width: 100%;
  height: 20px;
  background-color: aqua;
}
</style>

view视图:

点击修改后:

 可以发现两个组件都发生了更改,造成这种的原因是什么呢?

还是因为复杂数据类型的存放问题,复杂数据类型存储在堆中,用的是同一个地址。

用图的表示:

 直接用新变量替代:

<template>
  <div class="">
    <div class="aa" />
    <h1>我是子组件的</h1>
    <div v-for="(item, index) in cc" :key="index">
      <div>{
   
   { item.name }}-----{
   
   { item.age }}</div>
    </div>
    <button @click="fn">点击修改</button>
  </div>
</template>

<script>
export default {
  props: {
    num: {
      type: Array,
    },
  },
  data() {
    return {
      cc: this.num,
    };
  },
  name: "",
  methods: {
    fn() {
      this.cc[0].name = "一万次悲伤";
    },
  },
};
</script>

<style scoped>
.aa {
  width: 100%;
  height: 20px;
  background-color: aqua;
}
</style>

错误的,因为地址并不用发生变化,这必然要用到深拷贝。

我们深拷贝一份在来看下:

<template>
  <div class="">
    <div class="aa" />
    <h1>我是子组件的</h1>
    <div v-for="(item, index) in newdata" :key="index">
      <div>{
   
   { item.name }}-----{
   
   { item.age }}</div>
    </div>
    <button @click="fn">点击修改</button>
  </div>
</template>

<script>
export default {
  props: {
    num: {
      type: Array,
    },
  },
  data() {
    return {
      newdata: [...this.num],
    };
  },
  name: "",
  methods: {
    fn() {
      this.newdata.push({
        name: "小芳",
        age: 18,
      });
    },
  },
};
</script>

<style scoped>
.aa {
  width: 100%;
  height: 20px;
  background-color: aqua;
}
</style>

view:

父子组件不再建立联系,实现了想要的效果。

三.可以通过ref来控制弹窗

<template>
  <div class="">
    <One :data1="isShow" ref="add" />
    <button @click="fn">点击</button>
  </div>
</template>

<script>
import One from "@/components/One.vue";
export default {
  components: {
    One,
  },
  data() {
    return {
      isShow: false,
    };
  },
  name: "",
  methods: {
    fn() {
      this.$refs.add.isShow = true;
    },
  },
};
</script>

<style scoped></style>

<template>
  <div class="">
    <div class="aa" v-if="isShow"></div>
    <h1>子组件 {
   
   { isShow }}</h1>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isShow: false,
    };
  },
  name: "",
  methods: {},
};
</script>

<style scoped>
.aa {
  width: 500px;
  height: 500px;
  background-color: pink;
}
</style>

 修改了子组件的值,并没有报错。

猜你喜欢

转载自blog.csdn.net/qq_59076775/article/details/124909375