vue2与vue3数据响应式对比之检测变化

vue2

由于javascript限制,vue不能检测数组和对象的变化

什么意思呢,举例子来说吧
深入响应式原理

对象

比如说我们在data里面定义了一个info的对象

html 复制代码
<template>
  <div id="app">
    <div>姓名: {{ info.name }}</div>
    <div>年龄: {{ info.age }}</div>
    <div>地址: {{ info.address }}</div>
    <button @click="handleAddProp">追加prop</button>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      info: {
        name: "于十月",
        age: 28,
      },
    };
  },
  methods: {
    handleAddProp() {
      this.info.address = "山东省济南市";
    },
  },
};
</script>

我们在info对象里面只定义了name,age两个字段,然后我们在页面展示了name,age,address三个字段,我们想再点击按钮的时候,给address赋值,这个时候会有什么效果?可以自己试一下,效果就是,页面上没有任何效果也就是说我们在info声明的时候没有address这个字段,后续我们在操作中去修改这个字段,vue是不能给我们检测到的

所以要想实现效果的话官方给提供实现方案

  • Vue.set或者this.$set
  • Object.assign()或者_.extend()

具体实现如下:

html 复制代码
<template>
  <div id="app">
    <div>姓名: {{ info.name }}</div>
    <div>年龄: {{ info.age }}</div>
    <div>地址: {{ info.address }}</div>
    <div>手机号: {{ info.phone }}</div>
    <button @click="handleAddProp">追加prop</button>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      info: {
        name: "于十月",
        age: 28,
      },
    };
  },
  methods: {
    handleAddProp() {
      // this.info.address = "山东省济南市";
      this.$set(this.info, "address", "山东省济南市");
      // or
      this.info = Object.assign({}, this.info, { phone: 138888888888 });
    },
  },
};
</script>

数组

vue不能检测以下数组的变动

  • 当你利用索引直接设置一个数组项时 vm.items[index] = newValue
  • 当你修改数组的长度时 vm.items.length = newLength
html 复制代码
<template>
  <div id="app">
    <p v-for="(val, index) in list" :key="index">{{ val }}</p>
    <button @click="handleChangeList">修改数组项</button>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      list: [1, 2, 3, 4],
    };
  },
  methods: {
    handleChangeList() {
      this.list[0] = "小明";
    },
  },
};
</script>

我们希望点击按钮的时候1能够变成小明,但发现并没有任何效果,要想实现的话也可以使用$set

html 复制代码
<template>
  <div id="app">
    <p v-for="(val, index) in list" :key="index">{{ val }}</p>
    <button @click="handleChangeList">修改数组项</button>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      list: [1, 2, 3, 4],
    };
  },
  methods: {
    handleChangeList() {
      // this.list[0] = "小明";
      this.$set(this.list, 0, "小明");
    },
  },
};
</script>

vue3

我们可以按照上面的数据在vue里面试一下

html 复制代码
<script setup>
  const info = reactive({
    name: '于十月',
  });

  const list = ref([1, 2, 3]);

  const handleAddProp = () => {
    info.address = '山东省济南市';
    info.age = 28;
  };

  const handleChangeList = () => {
    list.value[0] = '小明';
  };
</script>

<template>
  <div>姓名: {{ info.name }} -- 年龄 {{ info.age }} --- {{ info.address }}</div>
  <a-button @click="handleAddProp">修改prop</a-button>
  <div>
    <p v-for="(val, index) in list" :key="index">{{ val }}</p>
  </div>
  <a-button @click="handleChangeList">修改数组的值</a-button>
</template>

然后发现不需要做特殊的处理,就可以实现我们想要的效果

其实这里面就牵扯到了关于vue2与vue3内部实现响应式的原理了,vue2使用defineProperty,vue3的时候直接放弃用了proxy

具体怎么他俩怎么实现的后面在写

这就可以延伸出来很多面试题,比如

1.vue2跟vue3在处理数据这一块有什么不同吗?

2.vue2里面我往对象里面新增一个属性,这个时候界面会有变化吗?

3.为什么使用 set之后就可以实现数据的响应, set的实现原理是什么?

4.vue2在处理对象和数据的时候有什么弊端?

。。。。。

即使没搞明白深层原理,把官方文档看明白,碰到这些问题也会迎刃而解~

相关推荐
Ruihong11 分钟前
你的 Vue KeepAlive 组件,VuReact 会编译成什么样的 React 代码?
vue.js·react.js·面试
Ruihong16 分钟前
你的 Vue slot 插槽,VuReact 会编译成什么样的 React 代码?
vue.js·react.js·面试
计算机魔术师34 分钟前
【AI面试八股文 | 面试题库】AI工程师面试题库:100+来源的系统性解题思路
人工智能·面试·职场和发展·ai工程师面试·system design
SamDeepThinking39 分钟前
学数据结构到底有什么用
java·后端·面试
闲人xyz1 小时前
01|把一次用户请求做成可持续执行的回合:主循环才是 Agent 的骨架
算法·面试
程序员清风1 小时前
独立开发者必看:推荐几个可直接用的开源项目!
java·后端·面试
落魄江湖行1 小时前
基础篇三 一行 new String(“hello“) 到底创建了几个对象?90% 的人答错了
java·面试·八股文
青衫码上行1 小时前
【从零开始学习JVM】栈中存的是指针还是对象 + 堆分为哪几部分
java·jvm·学习·面试
前端缘梦1 小时前
深入理解React Fiber架构:渲染流程与双缓冲机制全解析
前端·react.js·面试
Ruihong1 小时前
Vue v-slot → 用 VuReact 转换后变成这样的 React 代码
vue.js·react.js·面试