vue3优点
性能的提升
-
打包大小减少41%
-
初次渲染块55%,更新渲染快133%
-
内存减少54%
源码的升级
-
使用Proxy代替defineProperty实现响应式
-
重写虚拟DOM的实现和Tree-Shaking
相对于vue2,vue3是一个很大的进步,那么我们现在就来看看,vue3中的一些方法和属性该怎么用吧
setup函数
setup是Vue3.0中一个新的配置向,值为一个函数
setup是所有Composition API(组合API) ”表演的舞台“
组件中所有用到的:数据、方法等等,均要配置在setup中
setup函数的两种返回值:
- 若返回一个对象,则对象中的数据、方法、在模板中均可直接使用(重点)
- 若返回一个渲染函数,则可以自定义渲染内容
注意
- 尽量不要和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}} 单价:{{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>
执行结果
vue2.0的响应式原理和vue3.0的响应式原理
vue2.0的响应式
-
对象类型:通过Object.definedProperty()对属性的读取、修改进行拦截(数据劫持)
-
数组类型:通过重写更新数据的一系列方法来实现拦截。(对数组的方法进行了包裹)
存在问题
-
新增属性,删除属性都不会刷新界面
-
直接通过下标修改数组,界面不会自动更新
vue3.0的响应式原理
- 通过Proxy(代理):拦截对象中任意属性的变化,包括:属性的读写,属性的添加,属性的删除等
- 通过Reflect(反射):对被代理对象的属性进行操作
就很好的解决了vue2.0的问题