性能的提升
打包大小减少41%
初次渲染块55%,更新渲染快133%
内存减少54%
源码的升级
使用Proxy代替defineProperty实现响应式
重写虚拟DOM的实现和Tree-Shaking
相对于vue2,vue3是一个很大的进步,那么我们现在就来看看,vue3中的一些方法和属性该怎么用吧
setup是Vue3.0中一个新的配置向,值为一个函数
setup是所有Composition API(组合API) ”表演的舞台“
组件中所有用到的:数据、方法等等,均要配置在setup中
setup函数的两种返回值:
<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函数的作用是定义一个响应式的数据
其语法为:const xxx = ref(“value”)
{{xxx}}<template>
<div>
<p>{{name1}}p>
<p>{{name2}}p>
<button @click="changName">changNamebutton><br><br>
<button @click="lookName">lookNamebutton>
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函数的作用是定义一个对象类型的响应式数据
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">changebutton>
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>

就是监听了value的改变 劫持value属性的setter getter
因此ref一般用在基本数据,或者引用数据的嵌套层级不深得数据上
跟ref一样 但是底层采用的是ES6的Proxy代理了整个引用数据
计算属性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}} 单价:{{el.price}}元span>
<button>-button>
<span>{{el.count}}span>
<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>

对象类型:通过Object.definedProperty()对属性的读取、修改进行拦截(数据劫持)
数组类型:通过重写更新数据的一系列方法来实现拦截。(对数组的方法进行了包裹)
存在问题
新增属性,删除属性都不会刷新界面
直接通过下标修改数组,界面不会自动更新
就很好的解决了vue2.0的问题