vue3对比vue2新增特性

ref,reactive

当点击num,和info,去修改它们的值,页面上也会同步修改过来,相当于vue2中在data函数里面声明响应式数据,但是比vue2更加完善。在vue2中使用Object.defineProperty() 来实现响应式,存在一些局限性,比如无法检测对象属性的添加和删除,对于数组的某些操作(如通过索引修改元素)也不能自动触发响应式更新(需要手动触发视图更新)。vue3使用基于js的proxy对象实现响应式,很好的解决了这个问题。

javascript 复制代码
<template>
  <div>
    <div  @click="numAdd">num:{{ num }}</div>
    <div @click="changeInfo">info:{{ info }}</div>
    
  </div>
</template>

<script setup>
import { reactive, ref } from "vue";

//ref创建基础数据类型的响应式处理
const num = ref(1);
//   reactive创建引用数类型的响应式处理
const info = reactive({ name: "zs", age: 12 });

const numAdd = () => {
  num.value++;
};
const changeInfo = () => {
  console.log(info);
  info.age = 99;
  info.name = "张三";
};
</script>

<style></style>

组合式函数

组合式函数是 Vue 3 中一种复用逻辑的方式,通过将相关的逻辑封装到一个函数中,可以在多个组件中复用。

创建tools文件夹,创建文件demoTool.js

javascript 复制代码
import { ref } from 'vue';

function useCounter() {
  const count = ref(0);
  const increment = () => {
    count.value++;
  };

  return {
    count,
    increment
  };
}

export  {useCounter}
javascript 复制代码
<template>
  <div>
    <div @click="countAdd()"> count:{{count}}</div>
  </div>
</template>

<script setup>
import {useCounter} from '@/tools/demoTool'
//解构出count变量,和count+1的方法
const {count,increment}=useCounter();

const countAdd=()=>{
    increment();
    console.log('count',count.value);
}




</script>

<style>

</style>

provide,inject,defineProps,defineEmits

provide,inject跨组件传参,defineProps,defineEmits父子组件传参。详细可以看下这里,本文就不赘述了。vue3组件传参

shallowReactive,shallowRef

`shallowReactive`与 `reactive` 类似,但仅对对象的顶层属性进行响应式处理,深层嵌套的对象不会被转为响应式。适用于处理大型对象,仅需要对顶层属性进行响应式更新的场景,可减少不必要的响应式转换开销。

`shallowRef`与 `ref` 类似,但仅对 `.value` 的赋值操作进行响应式追踪,而不会对 `.value` 指向的对象内部属性变化进行响应式处理。当只关心引用的变更,而不关心引用对象内部的变化时可以使用。

javascript 复制代码
<template>
  <div>
    <h2>shallowReactive</h2>
    <p>Name: {{ info.name }}</p>
    <p>Detail Name: {{ info.detail.name2 }}</p>
    <button @click="changeName">Change Names</button>
    <button @click="changeName2">Change Names</button>
    <br />
    <h2>shallowRef</h2>
    <p>Name: {{ info2.name }}</p>
    <p>Detail Name: {{ info2.detail.name }}</p>
    <P>age :{{ info2.detail.age }}</P>
    <button @click="changeInfo">Change Names</button>
    <button @click="changeInfo2">Change Names</button>
  </div>
</template>

<script setup>
import { shallowReactive, shallowRef } from "vue";

const info = shallowReactive({
  name: "zs",
  detail: {
    name2: "ls",
    age: 12,
  },
});
const info2 = shallowRef({ name: "111", detail: { name: "a111", age: 22 } });
const changeInfo = () => {
  info2.value = { name: "222", detail: { name: "a222", age: 33 } };
  //   info2.value.name = "qqq";  单独修改根目录属性是不生效的
};
const changeInfo2 = () => {
  // 不生效的 不会对内部属性对象进行响应式处理
  info2.value.detail.name = "张三";
};
// 视图会更新
const changeName = () => {
  info.name = "张三";
};
// 视图不会更新
const changeName2 = () => {
  info.detail.name2 = "李四";
};
</script>

针对于shallowReactive还有一种情况,如果在一个方法里面去同时修改第一层和第二层的name,那么视图也是会更新的,这是因为Vue 的响应式系统在更新时会有一个批量处理的机制。当修改第一层响应式属性info.name时,Vue 会开启一个更新队列,在这个队列处理过程中,虽然info.detail.name不是响应式的,但由于更新队列在处理其他更新,会顺带把相关的 DOM 重新渲染了 。演示下:

javascript 复制代码
<template>
  <div>
    {{ info.name }}-{{ info.detail.name }}
    <button @click="changeInfo">修改info</button>
  </div>
</template>

<script setup>

import {provide ,reactive ,shallowReactive,isReactive} from 'vue'

const info=shallowReactive({name:'zs',detail:{name:'ls',age:12}});

const changeInfo=()=>{
    info.name='张三';
    info.detail.name='李四';
    console.log(isReactive(info.detail.name));
}
</script>

当点击按钮的时候 info.detail.name视图也更新了,从控制台打印信息看到它不是响应式的。

end

如有误欢迎指正,后续会继续补充。

相关推荐
拉不动的猪15 分钟前
前端常见数组分析
前端·javascript·面试
小吕学编程32 分钟前
ES练习册
java·前端·elasticsearch
Asthenia041239 分钟前
Netty编解码器详解与实战
前端
袁煦丞44 分钟前
每天省2小时!这个网盘神器让我告别云存储混乱(附内网穿透神操作)
前端·程序员·远程工作
Mr.app1 小时前
vue mixin混入与hook
vue.js
一个专注写代码的程序媛2 小时前
vue组件间通信
前端·javascript·vue.js
一笑code2 小时前
美团社招一面
前端·javascript·vue.js
懒懒是个程序员2 小时前
layui时间范围
前端·javascript·layui
NoneCoder2 小时前
HTML响应式网页设计与跨平台适配
前端·html
凯哥19702 小时前
在 Uni-app 做的后台中使用 Howler.js 实现强大的音频播放功能
前端