Vue3学习笔记

第一章 Vue3

1.Vue3有哪些提升?

①性能的提升
打包大小减少41%、初次渲染快55%,更新渲染快133%,内存减少54%……
②源码的升级

  • 使用Proxy代替defineProperty实现响应式。
  • 重写虚拟DOM的实现和Tree-Shaking。 ……
    ③拥抱TypeScript
    Vue3可以更好的支持TypeScript
    ④新的特性
    (1)Composition API(组合API) setup配置、ref与reactive、watch与watchEffect、provide与inject
    (2)新的内置组件 Fragment、Teleport、Suspense
    (3)其他改变 新的生命周期钩子、data选项始终被声明为一个函数、移除keyCode支持作为v-on的修饰符

2.Vue3的main.js变化

①引入的不再是Vue的构造函数,而是一个名为createApp的工厂函数。
②创建应用实例对象——app(类似于之前的Vue2中的vm,但app比vm更轻)
③不兼容vue2的写法。

import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App);
app.mount('#app')
console.log(app)

在这里插入图片描述

3.ref和reactive(对比)

角度refreactive
定义数据角度基本类型数据,(也可以用来定义对象类型数据,它内部会自动通过reactive转为代理对象)对象(或数组)类型数据
原理角度通过Object.defineProperty() 的get与set来实现响应式(数据劫持)通过使用Proxy来实现响应式(数据劫持),并通过Reflect操作源对象内部的数据。
使用角度操作数据需要.value,读取数据时模板中直接读取不需要.value。操作数据与读取数据,均不需要.value。
语法const xxx = ref(initValue);
创建一个包含响应式数据的引用对象(reference 对象,简称ref对象)
let dog = ref('汤姆');
  const person = ref({
  name:'月亮',
  age:20
});
console.log(dog);
console.log(person);
const 代理对象 = reactive(源对象)
接收一个对象(或数组),
返回一个代理对象(proxy对象)
const person = reactive({
name:'月亮',
age:20
});
console.log(person);
图示在这里插入图片描述在这里插入图片描述

4.Object.defineProperty()和proxy()

Object.defineProperty()proxy()
使用方式多个属性需要循环。添加get()、set()、deleteProperty()函数实现响应式,
没有添加之前只是代理。能捕获到对属性的任何一种操作,不用循环遍历。
使用在这里插入图片描述vue3的响应式不仅仅用了代理还用到了反射。在这里插入图片描述在这里插入图片描述
图示在这里插入图片描述在这里插入图片描述

5.vue3中的computed、watch

import { reactive,computed,watch} from 'vue' 能用vue2里的computed和watch配置项,但是混合不好,vue3将计算属性变为组合式的API,在setup()函数中使用。

computedwatch
使用在这里插入图片描述在这里插入图片描述可以调用多次watch函数:
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
问题暂无用reactive定义的对象,watch监视旧值监视不到了。即使是用ref定义,但是其实其value还是用了proxy代理,监视对象.value最后oldValue还是有问题。不是.value监视就需要开启深度监视,也能监视到value中的proxy对象。在这里插入图片描述
不管嵌套的数据有多深,都能监视到,默认强制开启深度监视,deep:false也关不掉。但是对于监视一个代理对象里的属性对象时,深度监视没有开启,oldValue也有问题。在这里插入图片描述

6.vue3的watchEffect()函数

watchEffect()监视回调中用到了什么数据就监视那个数据。

 let sum = ref(7);
 watchEffect(()=>{
   const x1 = sum.value;
   console.log(x1);
 })

7.生命周期

在这里插入图片描述 在这里插入图片描述 组合式API写的生命周期钩子比配置项的要快一些: 在这里插入图片描述

8.自定义hook函数

新建一个文件夹hooks,里面都是就是文件。
什么是hook?——本质上是一个函数,把setup函数中使用的Composition API继续宁了封装。
类似于vue2中的mixin。
自定义hook的优势:复用代码,让setup中的逻辑更清楚易懂。
使用export default function(){return 需要的数据}

9.toRef

作用:创建一个ref对象,其value值指向另一个对象中的某个属性。
语法:const name = toRef(person,'name');
对于深层次的对象,如果setup中直接return {此对象},以后模板取属性值需要person.属性很麻烦。
如果直接return {属性名:对象.属性名},不得行!!!此时属性名是自己新定义的属性了,后面就是把值给这个属性名,不能响应式了。记住对象.属性名就是个值!!!
return { age:toRef(sum,'age'),}此时age响应式。 ...toRefs(对象),拆出来第一层

第二章 不太常用的API

1.shallowReactive与shallowRef

shallowReactive:只处理对象最外层属性的响应式(浅响应式)
shallowRef:只处理基本数据类型的响应式,不进行对象的响应式处理。
什么时候使用?
如果有一个对象数据,结构比较深,但变化时只是外层属性变化==>shallowReactive
如果有一个对象数据,后续功能不会修改对象中的属性,而是生成新的对象来替换==>shallowRef

2.readonly与shallowReadonly

readonly:让一个响应式数据变为只读的(深只读),let person = readonly(person),对象里的数据改不了。
shallowReadonly:让一个响应式数据变为只读的(浅只读),对于对象外层只读 应用:不希望被修改时。

3.toRaw与markRaw

toRaw:将一个由reactive生成的响应式对象转为普通对象。(只能处理reactive标记的对象)
使用场景:用于读取相应是对象对应的普通对象,对这个普通对象所有的操作,不会引起页面更新。
markRaw:标记一个对象,使其永远不会再成为响应式对象。
使用场景:1.有些值不应被设置为响应式的,例如复杂的第三方类库等。
2.当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能。

4.customRef

作用:创建一个自定义的ref,并对其依赖项跟踪和更新触发进行显式控制。

let keyword = myref('hello',500);
function myref(value,delay){//自定义ref
    let timer;
    return customRef((track,trigger)=>{//自定义的逻辑
        return {
            get:function(){//读取该数据时
            track();//提前说明要追踪数据
            return value;
            },
            set:function(newvalue){
                value=newvalue;
                clearTimeout(timer);
                timer = setTimeout(()=>{
                    trigger();//通知vue重新去解析模板
                },delay)
            }
        } //必须返回一个对象
    });
}

5.provide与inject

作用:实现祖孙组件间的通信。(父子组件一般不用这个,而用props)
应用:父组件有一个provide选项来提供数据,子组件有一个inject选项来开始使用这些数据。

父组件:

  let car = reactive({
      name:'奔驰',
      price:'40w'
    });
    provide('car',car);//给自己的后代提供数据

子组件

  let car = inject('car');

6.响应式数据判断API

isRef: 检查一个值是否为一个ref对象。

isReactive:检查一个对象是否由reactive创建的响应式代理。

isReadonly:检查一个对象是否由readonly创建的只读代理。

isProxy:检查一个对象是否由reactive或者readonly方法创建的代理。

第三章 其他

1.Options API存在的问题与Composition API的优势

----Options API存在的问题----Composition API的优势
使用传统Options API中,新增或者修改一个需求,就需要分别在data,method,computed里修改。(功能的数据、方法、监视都拆散了,多个功能的数据等都混在了一起。)可以更加优雅的组织代码、函数,让相关功能的代码更加有序地组织在一起。

2.新的组件

(1)Fragment

在Vue2中:组件必须有一个根标签。
在Vue3中:组件可以没有根标签,内部会将多个标签包含在一个Fragment虚拟元素中。
好处:减少标签层级,减少内存占用。

(2)Teleport组件

Teleport是一种能够将我们的组件html结构移动到指定位置的技术。

(3)Suspense组件

等待异步组件时渲染一些额外内容,让应用有更好的用户体验。 理解:suspense标签里准备了两个插槽,一个用于防止真正展示的组件,一个展示loading正在加载提示。

 <Suspense>
      <template v-slot:default>
            <Child/>
      </template>
      <template v-slot:fallback>
          <h3>加载中</h3>
      </template>
</Suspense>
import {defineAsyncComponent} from 'vue'
const Child = defineAsyncComponent(()=>import('./Child.vue'))

3.Vue3中的其他改变

  1. 移除keyCode作为v-on的修饰符,同时也不再支持config.keyCodes
  2. 移除v-on:Click.native修饰符 对于自定义事件,需要在子组件中声明:
export default{
    emits:['close']
}
  1. 移除过滤器filter:过滤器虽然看起来很方便,但它需要一个自定义语法,打破打括号内表达式是"只是javascript"的假设,这不仅有学习成本,而且有实现成本,建议用方法或者计算属性去替换过滤器。