1.性能的提升
打包大小减少41%
初次渲染快55%, 更新渲染快133%
内存减少54%2.源码的升级
使用Proxy代替defineProperty实现响应式
重写虚拟DOM的实现和Tree-Shaking
3.拥抱TypeScript
Vue3可以更好的支持TypeScript
4.新的特性
- Composition API(组合API)
setup配置
ref与reactive
watch与watchEffect
provide与inject
- 新的内置组件
Fragment
Teleport
Suspense
- 其他改变
新的生命周期钩子
data 选项应始终被声明为一个函数
移除keyCode支持作为 v-on 的修饰符5 组合式API和配置项API
- 使用组合式API
- 配置项API
{ name:'xx', data:function(){}, methods:{} }
∙ " role="presentation"> 方式一:vue-cli创建与vue2中创建一样
∙ " role="presentation"> 方式二:创建vue3最新版nup init vue@latest
∙ " role="presentation"> 方式三:创建vue3.0.4版本
// 创建命令 npm init vite-app // 进入工程目录 cd // 安装依赖 npm install
setup
函数中可以使用CompositionAPI组合式api, 可以使用响应式 API 来声明响应式的状态,在setup()
函数中返回的对象会暴露给模板和组件实例,setup
在created实例被完全初始化之前执行,所以在setup中this已经不是vue2中的vc对象而是一个代理对象。- 代码演示
<h1>{{name}}h1> <h1>{{age}}h1> <button @click="handleAdd">年龄加一button> <script> export default { name: 'App', setup() { let name = '大帅哥' let age = 18 let handleAdd = () => { age= age+1 console.log(age) } return { name,age,handleAdd } } } script>
∙ " role="presentation"> 在setup中定义的变量和函数必须要return出去才能在模版中使用
∙ " role="presentation"> 上面的写法变量可以渲染页面,但是没有响应式前端打印数据变化但是变量不会改变
上诉方式直接定义的变量和函数没有响应式不能改变变量和页面的渲染
- ref:基本数据类型加响应式(数字、字符串、布尔值),在模版中使用
- reactive:对象、数组加响应式
∙ " role="presentation"> 需要导入使用
import {ref,reactive} from 'vue'
∙ " role="presentation"> 代码演示
<h3>{{ name }}h3> <h3>{{ age }}h3> <h3>{{User.arr}}h3> <button @click="handleAdd">点击age+1button> <button @click="handleChangeName">点击name+nbbutton> <button @click="handleChangeUser">点击更改用户button> <script> import {ref, reactive} from 'vue' export default { name: 'App', setup() { let age = ref(18) // age 已经不是数字了,是RefImpl的对象 let name = ref('大帅哥') let User = reactive({ arr:[{name:'大帅哥', age:18, sex:'男'}] }) let handleAdd = () => { age.value = age.value + 1 console.log('点击后age是', age.value) } function handleChangeName(){ name.value=name.value+'nb' console.log(name.value) } function handleChangeUser(){ User.arr = { name:'大美女', age:'18岁的妹妹一朵花', sex:'女' } console.log(User) } return { age, name,User, handleAdd,handleChangeName,handleChangeUser } } } script>
∙ " role="presentation"> 计算属性:computed函数与vue2中的使用一样- 引入computed方法
import { computed } from 'vue'
- 代码演示:提供一个姓与一个名通过计算属性相结合
<template> <hr> <input type="text" v-model="person.firstName"> <br> <input type="text" v-model="person.lastName"> <br> <input type="text" v-model="person.fullName"> template> <script> import {ref, reactive, computed} from 'vue' export default { name: 'App', setup(){ let person = reactive({ firstName:'大', lastName:'帅哥', }) person.fullName = computed({ get() { return person.firstName + '-' + person.lastName }, set(value) { const nameArr = value.split('-') person.firstName = nameArr[0] person.lastName = nameArr[1] } }) return {person} } } script>
∙ " role="presentation"> 监听属性:watch函数与vue2中用法一样,在vue3中多了watchEffect用来监听 ref 定义的响应式数据- 引入方法
import {watch, watchEffect} from 'vue'
- 代码演示
<template> <h1>监听属性h1> <hr> <input type="text" v-model="name">--->{{ name }} template> <script> // 计算属性,监听属性 import {computed, watch, ref, reactive, watchEffect} from 'vue' export default { name: 'App', setup() { let name = ref('abc') // 定义监听属性 watch(name, (newValue, old) => { console.log('name变了') // console.log(old) // console.log(newValue) }) // 只要函数中使用的变量发生变化,它就会触发 watchEffect(() => { // 只要该函数中使用的变量发生变化,它就会触发 // let a = name.value + '?' console.log('watchEffect配置的回调执行了') }) return { name } } } script>
Vue3生命周期与Vue2生命周期差别
∙ " role="presentation"> 在vue3中可以继续使用Vue2中的生命周期钩子,但有两个被改名:- beforeDestroy 改名为 beforeUnmount
- destroyed 改名为 unmounted
∙ " role="presentation"> Vue3与Vue2生命周期钩子对应关系图 如下:
∘ " role="presentation"> vue3 中的 hooks 函数相当于 vue2 里面的 mixin 混入,不同在于 hooks 是函数
∘ " role="presentation"> vue3 中的 hooks 函数可以提高代码的复用性,能够在不同的组件当中都利用 hooks 函数- 功能要求
现在我们要写一个功能当我们点击页面时展示当前鼠标点击位置的x,y轴位置,然后在多页面组件中用这个功能
- 思路逻辑
在srf下创建一个hooks目录把需要重复使用的功能写在下面,当页面组件中需要使用到时只需要导入目录下具体功能的文件即可
- 代码演示
新建:hook/usePoint.js
import {onMounted, onUnmounted, reactive} from "vue"; export default function () { let p = reactive({ x: 0, y: 0 }) function getPoint(event) { console.log(event) p.x = event.pageX p.y = event.pageY } // 声明周期钩子的onMounted,当页面挂载就会执行 onMounted(() => { // 给数鼠标点击增加监听,当点击鼠标,就会执行这个函数 window.addEventListener('click', getPoint) }) // 组件被销毁时,把功能去掉 onUnmounted(() => { window.removeEventListener('click', getPoint) }) return p }在页面组件中引入使用
<template> <h2>x坐标是:{{ p.x }},y坐标是:{{ p.y }}h2> template> <script> import {reactive, onMounted, onUnmounted} from 'vue' import usePoint from '../hook/uesPoint.js' export default { name: "Point", setup() { let p = usePoint() return {p} } } script> <style scoped> style>
将一个
响应式对象
,转换为普通对象
,并且将其中的属性转换为Ref
对象...toRefs通俗的可以理解为将ref或reactive中定义的变量解压赋值
<template> <h1>toRefsh1> <h1>人名是:{{ name }},年龄:{{ age }}h1> template> <script> import {toRefs, reactive} from 'vue' export default { name: 'App', setup() { let data = reactive({ name: '大帅哥', age: 18, }) return { ...toRefs(data), } } }