Vue3.0之Vue3的优点,setup函数,ref函数,reactive函数,ref 和reactive的响应式设计原理,vue2.0的响应式

vue3优点

性能的提升

  • 打包大小减少41%

  • 初次渲染块55%,更新渲染快133%

  • 内存减少54%

源码的升级

  • 使用Proxy代替defineProperty实现响应式

  • 重写虚拟DOM的实现和Tree-Shaking

相对于vue2,vue3是一个很大的进步,那么我们现在就来看看,vue3中的一些方法和属性该怎么用吧

setup函数

setup是Vue3.0中一个新的配置向,值为一个函数

setup是所有Composition API(组合API) ”表演的舞台“

组件中所有用到的:数据、方法等等,均要配置在setup中

setup函数的两种返回值:

  1. 若返回一个对象,则对象中的数据、方法、在模板中均可直接使用(重点)
  2. 若返回一个渲染函数,则可以自定义渲染内容

注意

  • 尽量不要和Vue2.x配置混用
  • Vue2.x配置(data,methods,computed…)中可以访问setup中的属性,方法
  • 但在setup中不能访问到Vue2.x配置(data,methods,computed…)
  • 如有重名,setup优先
  • setup不能是一个async函数,因为返回值不再是return的对象,而是Promise,模板看不到return对象中的属性

<template>
  <div>
    <p>{{ a }}</p>
    <p>{{ b }}</p>
    <button @click="change">打印b的值</button>
  </div>
</template>

<script>
export default {
  setup() {
    var a = 20;
    var b = [40, 80];
    function change() {
      console.log("打印b的值:" + b);
    }
    return { a, b, change };
  },
};
</script>


在这里插入图片描述

setup函数的语法糖

setup属性 会让打包工具打包时 直接帮我们把setup函数内部声明的变量/函数 return 然后组件就可以使用了

就不必专门去写setup函数

<template>
  <div>
    <p>{{a}}</p>
    <p>{{b}}</p>
    <button @click=change>打印a的值</button>
  </div>
</template>

<script setup>
  var a = 20;
  var b = 40
  function change(){
    console.log("打印a的值:"+a);
  }
</script>

<style lang="scss">
  
</style>

执行结果

在这里插入图片描述

ref函数

ref函数的作用是定义一个响应式的数据

其语法为:const xxx = ref(“value”)

  • 创建一个包含响应式的数据的引用对象(reference对象)
  • js中操作数据:xxx.value
  • 模板中读取数据不需要.value,直接<div>{{xxx}}</div>

注意

  • 接收的数据类型可以是基本数据类型也可以是引用数据类型
  • 基本类型的数据:响应式依然是靠Object.defineProperty()的get和set完成的
  • 对象类型的数据:内部“求助”了Vue3.0的一个新的函数------reactive函数
<template>
  <div>
    <p>{{name1}}</p>
    <p>{{name2}}</p>
    <button @click="changName">changName</button><br><br>
    <button @click="lookName">lookName</button>
  </div>
</template>

<script setup>
	import {ref} from "vue"
  let name1 = "我是name";
  let name2 = ref("我是ref的name");
  // 执行了这个函数实际上name1的值也是改变了的,只是因为setup只会运行一次,所以页面数据不会改变
  let changName = function(){
    name1 = "我是改变后的name";
    name2.value = "我是改变后的ref的name";
    
  }
  let lookName = ()=>{
    console.log(name1);
    console.log(name2.value);
  }
</script>

执行结果

在这里插入图片描述

ref函数里面的值需要用点value的语法去取,才能改变

执行的函数里面如果有改变name1的值的话,name1的值其实也是改变了的,只是因为setup在加载组件期间只会运行一次,所以页面数据不会改变

reactive函数

reactive函数的作用是定义一个对象类型的响应式数据

ref 函数是基本数据类型改变时用到的函数,而reactive 函数就是复杂的类型数据要改变时用到的函数

其语法为:const 代理一个对象 = reactive(被代理的对象) 接收一个对象(或数组),返回一个代理器对象(proxy对象)

reactive定义的响应式数据是“深层次的”,内部基于ES6的Proxy实现,通过代理对象内部的数据都是响应式的

<template>
  <div>
    <p>obj1:{{obj1}}</p>
    <p>obj2:{{obj2}}</p>
    <p>obj1:{{obj1.son.books[0].title}}</p>
    <p>obj1:{{obj1.son.books[0].price}}</p>
    <p>obj2:{{obj2.son.books[0].title}}</p>
    <p>obj2:{{obj2.son.books[0].price}}</p>
    <button @click="change">change</button>
  </div>
</template>

<script setup>
import {ref, reactive} from 'vue'
let obj1 = ref({name:"ben",son:{name:"benson",books:[{title:"web",price:24}]}});
const obj2 = reactive({name:"jack",son:{name:"jackson",books:[{title:"html",price:56}]}});
let change = ()=>{
  obj1.value.son.books[0].title = "荷塘月色";
  obj1.value.son.books[0].price = 66;
  obj2.son.books[0].title = "围城";
  obj2.son.books[0].price = 35;
  console.log(obj1);
  console.log(obj2);
}
</script>


执行结果

在这里插入图片描述

ref响应式设计原理

就是监听了value的改变 劫持value属性的setter getter
因此ref一般用在基本数据,或者引用数据的嵌套层级不深得数据上

reactive响应式设计原理

跟ref一样 但是底层采用的是ES6的Proxy代理了整个引用数据

计算属性computed

计算属性computed跟vue2.0的效果一样,只是写法上稍许不同

vue2.0是直接在methods里面写computed方法,而现在直接导入computed,然后跟ref,reactive一样的使用方法

<template>
  <div>
    <h1>{{msg}}</h1>
    <div v-for="(el,index) in arr" :key="index">
      <span>{{el.title}} &nbsp; 单价:{{el.price}}元</span> &nbsp;
      <button>-</button>&nbsp;
			<span>{{el.count}}</span>&nbsp;
			<button @click="Add(index)">+</button>
    </div>
    <p>{{total}}元</p>
  </div>
</template>

<script setup>
import { computed, reactive } from "vue";
let msg = "今天菜品";
let arr = reactive([
  {
    title: "鱼香肉丝",
    price: 23,
    count: 2,
  },
  {
    title: "宫保鸡丁",
    price: 34,
    count: 1,
  },
  {
    title: "麻婆豆腐",
    price: 15,
    count: 2,
  },
  {
    title: "糖醋鲤鱼",
    price: 46,
    count: 3,
  },
]);
let total = computed(()=>{
  console.log("计算总价");
  return arr.reduce((n1,n2)=>{
    return n1+n2.price*n2.count
  },0)
  
})
function Add(index){
  arr[index].count++;
}
</script>

执行结果

在这里插入图片描述

vue2.0的响应式原理和vue3.0的响应式原理

vue2.0的响应式

  • 对象类型:通过Object.definedProperty()对属性的读取、修改进行拦截(数据劫持)

  • 数组类型:通过重写更新数据的一系列方法来实现拦截。(对数组的方法进行了包裹)

存在问题

  • 新增属性,删除属性都不会刷新界面

  • 直接通过下标修改数组,界面不会自动更新

vue3.0的响应式原理

  • 通过Proxy(代理):拦截对象中任意属性的变化,包括:属性的读写,属性的添加,属性的删除等
  • 通过Reflect(反射):对被代理对象的属性进行操作

就很好的解决了vue2.0的问题

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值