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

本文探讨了简单数据类型与复杂数据类型在Vue组件中的操作,包括不可修改的简单类型、复杂类型修改的正确途径(深浅拷贝)、通过props传递数组的原理,以及如何利用ref控制弹窗。重点讲解了数据类型存储位置和深拷贝的重要性。
摘要由CSDN通过智能技术生成

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

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

<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>

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值