2020年9月发布的正式版
Vue3支持大多数的Vue2的特性
Vue中设计了一套强大的composition组合APi代替了Vue2中的option API ,复用性更强了
更好的支持TS
最主要: Vue3中使用了Proxy配合Reflect 代替了Vue2中Object.defineProperty()方法实现数据的响应式(数据代理)
之前用的是Options API
export default{
data:""
computed:""
watch:""
mounted:""
}
Composition API
export default{
setup:(props,context){
ref();//或者reactive()
computed();
//自定义的函数
watchEffect()
onMounted()
}
}
重写了虚拟DOM,速度更快了
新的组件: Fragment(片段) / Teleport(瞬移) / Suspense(不确定)
设计了一个新的脚手架工具,vite
这里首先从setup开始说起
<template>
<h2>setup和ref的基本使用</h2>
<h3>{{ count }}</h3>
<button @click="updateCount">更新数据</button>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue'
export default defineComponent({
name: 'App',
// 需求:页面打开后可以直接看到一个数据,点击按钮后,该数据可以发生变化
// vue2的方式实现
// data() {
// return {
// count: 0, // 属性
// }
// },
// methods: {
// updateCount() { // 方法
// this.count++
// },
// },
// vue3的方式实现
// setup是组合API的入口函数
setup(){
// console.log('第一次')
// 变量
// let count = 0 // 此时的数据并不是响应式的数据(响应式数据:数据变化,页面跟着渲染变化)
// ref是一个函数,作用:定义一个响应式的数据,返回的是一个Ref对象,对象中有一个value属性,如果需要对数据进行操作,需要使用该Ref对象调用value属性的方式进行数据的操作
// html模版中是不需要使用.value属性的写法
// 一般用来定义一个基本类型的响应式数据
// count 的类型 Ref类型
const count = ref(0)
console.log(count)
// 方法
function updateCount(){
console.log('=====')
// 报错的原因:count是一个Ref对象,对象是不能进行++的操作
// count++
count.value++
}
// 返回的是一个对象
return {
// 属性
count,
// 方法
updateCount
}
}
})
</script>
ref这种写法简单,但也有弊端,经过尝试,我发现他只能监听一些如数字、字符串、布尔之类的简单数据而如果需要监听如json Array我们在vue2种都会使用$set来进行变更,到了vue3我们终于可以愉快的使用reactive来实现了。
具体如下
<template>
<h2>reactive的使用</h2>
<h3>名字:{{ user.name }}</h3>
<h3>年龄:{{ user.age }}</h3>
<h3>性别:{{ user.gender }}</h3>
<h3>媳妇:{{ user.wife }}</h3>
<hr />
<button @click="updateUser">更新数据</button>
</template>
<script lang="ts">
import { defineComponent, reactive } from 'vue'
export default defineComponent({
name: 'App',
// 需求:显示用户的相关信息,点击按钮,可以更新用户的相关信息数据
/*
reactive
作用: 定义多个数据的响应式
const proxy = reactive(obj): 接收一个普通对象然后返回该普通对象的响应式代理器对象
响应式转换是“深层的”:会影响对象内部所有嵌套的属性
内部基于 ES6 的 Proxy 实现,通过代理对象操作源对象内部数据都是响应式的
*/
setup() {
// const obj: any = { // 为了在使用obj.gender='男' 的时候不出现这种错误的提示信息才这么书写
const obj = {
name: '小明',
age: 20,
wife: {
name: '小甜甜',
age: 18,
cars: ['奔驰', '宝马', '奥迪'],
},
}
// 把数据变成响应式的数据
// 返回的是一个Proxy的代理对象,被代理的目标对象就是obj对象
// user现在是代理对象,obj是目标对象
// user对象的类型是Proxy
const user = reactive<any>(obj)
console.log(user)
// 方法
// function updateUser(){}
const updateUser = () => {
// 直接使用目标对象的方式来更新目标对象中的成员的值,是不可能的,只能使用代理对象的方式来更新数据(响应式数据)
// obj.name += '==='
// 下面的可以
// user.name += '=='
// user.age += 2
// user.wife.name += '++'
// user.wife.cars[0] = '玛莎拉蒂'
// user---->代理对象,user---->目标对象
// user对象或者obj对象添加一个新的属性,哪一种方式会影响界面的更新
// obj.gender = '男' // 这种方式,界面没有更新渲染
// user.gender = '男' // 这种方式,界面可以更新渲染,而且这个数据最终也添加到了obj对象上了
// user对象或者obj对象中移除一个已经存在的属性,哪一种方式会影响界面的更新
// delete obj.age // 界面没有更新渲染,obj中确实没有了age这个属性
// delete user.age // 界面更新渲染了,obj中确实没有了age这个属性
// 总结: 如果操作代理对象,目标对象中的数据也会随之变化,同时如果想要在操作数据的时候,界面也要跟着重新更新渲染,那么也是操作代理对象
// 通过当前的代理对象找到该对象中的某个属性,更改该属性中的某个数组的数据
// user.wife.cars[1] = '玛莎拉蒂'
// 通过当前的代理对象把目标对象中的某个数组属性添加一个新的属性
user.wife.cars[3] = '奥拓'
}
return {
user,
updateUser,
}
},
})
</script>
推荐文章
[点击进入](https://juejin.cn/post/6940454764421316644)