德胜云资讯,添加一些关于程序相关的内容,仅供大家学习交流(https://www.wxclwl.com)
日期:2023/03/23 18:16作者:蔡书玮人气:
--------------------
下栽の地止:https://www.itwangzi.cn/2479.html
--------------------
VUE3基础教程
vue3的新特性
vue3还有其他的改动,如废弃on、off、once实例方法、移除过滤器filters等,请查看官网文档。
一、createApp创建应用
createApp返回一个提供应用上下文的应用实,应用实例挂载的整个组件树共享同一个上下文,该上下文提供了先前在Vue 2.x中“全局”的配置。该实例不会被应用于其他实例的任何全局配置所污染,共享实例属性应附加到应用程序实例的config.globalProperties。
二、新增setup函数
新增setup方法代替beforeCreate 和 created, 在setup函数里面接收props和context获取 props、attrs、emit、slots。
三、新增三个组件
分别是Fragment、Suspense、Teleport。
1.Fragment
Fragment默认支持,可不写。
2.Suspense
suspense可以在组件渲染之前的等待时间显示指定内容。
父组件Suspense.vue
子组件SuspenseAsync.vue
3.Teleport
Teleport可以让子组件能够在视觉上跳出父组件,如父组件overflow:hidden,原理是在body下面渲染组件,也就是样式也无法继承。
四、css绑定JS变量
vue3通过在组件第一个元素上声明css3的变量,然后style标签里面引用的变量将会使用var的方式引用,可以解决vue2动态样式不分离、权重过高等问题。
五、生命周期对比
1. 在 Vue2 生命周期钩子函数名基础上加了 on。
2.
beforeDestory 和 destoryed 更名为 onBeforeUnmount 和 onUnmounted。
3. 然后删了两个钩子函数 beforeCreate 和 created。
4. 新增了两个开发环境用于调试的钩子onRenderTracked和onRenderTriggered。
六、Composition API
Composition API可以更好的逻辑复用和代码组织,同一功能的代码并不像以前一样太分散,虽然 Vue2 中可以用minxin来实现复用代码,但也存在问题,比如方法或属性名会冲突,代码来源也不清楚等。
用Proxy代替Object.defineProperty重构了响应式系统,可以监听到数组下标变化,及对象新增属性,因为监听的不是对象属性,而是对象本身,还可拦截 apply、has 等13种方法,还可以更方便的组合hooks。
1.setup
setup函数是一个新的组件选项,作为在组件内使用Composition Api的入口点。下面我们分为4个方面来讲解它:
· 调用时机
· this指向
· 函数参数
· 返回值
(1)调用时机
创建组件实例,然后初始化props,紧接着就调用setup函数。从生命周期的角度来看,它会在beforeCreate之前执行,也就是创建组件先执行setup、beforeCreate、create。
(2)this指向
由于不能在setup函数中使用data、methods,为了避免使用Vue出错,所以把setup函数中this修改为了undefined。
(3)函数参数
函数参数包含了props和context。
·props
接收组件传递过来的所有数据,并且都是响应式的。
注意一点,props数据不能使用解构,否则响应式数据失效。
·context
该参数提供一个上下文对象,从原来的2.x中选择性的暴露了一些属性,attrs、slots、emit。
上面,attrs和slots都是内部组件实例上对应项的代理,可以确保在更新后仍然还是最新的值,所以这里可以使用解构语法。
(4)返回值
可以将setup函数返回值渲染到页面上,但前提是setup返回值必须是一个对象,否则返回其它值则渲染无效。
2.Reactive
该方法接收一个参数{}创建一个响应式对象,跟Vue2.x的Vue.observable一样。如果该参数不是对象的话,也可以渲染到模板上,但不是响应式的数据。
3.Ref
该方法接收一个参数,可以是单个值,也可以是一个对象,并且都是响应式的数据。当传入一个对象时{},内部将调用reactive方法进行转换为响应式数据,返回值里面带有.value属性取值,当使用模板渲染的时候可省去.value。
4.Computed
该方法可以传入一个函数,默认该函数就是getter,不管getter返回值为一个ref响应式数据还是一个普通变量,数据都是只读不能改变。
传入一个对象set和get函数方法,这样便可以进行修改。
5.Readonly
该方法接收传入一个对象,默认是只读功能,是深层对象只读,不管嵌套多少层的属性都是只读状态。
6.WatchEffect
该方法接收一个函数并且立即执行,并当该函数里的变量变更时,重新执行该函数。该方法无法获取到原值,只能是改变之后的值。
如果要监听哪个值,需要在该函数里写出来,否则监听无效。
取消监听
有时候想在触发一定的条件后取消监听。这时可以执行watchEffect的返回值。
7.Watch
watch等同于Vue2.x中的this.$watch,watch需要监听特定数据,默认情况是懒执行,也就是只有当数据发生变化时才执行第二个参数函数。对比WatchEffect :
Watch允许用户
· 懒执行函数
· 更明确哪些状态改变触发监听器
· 可以监听获取到变化前后的值
监听单个值
监听多个值
监听多个值,返回的是一个数组对象。
七、生命周期系列
在Vue3.X也可以在setup函数下使用生命周期,这些钩子函数写法跟之前的生命周期写法不同。
注意:这些生命周期写法只能在setup函数下使用,在其它地方使用则会报错。下面来看一下这些钩子的写法,钩子函数里面是一个回调函数。
1.Provide && Inject
该方法和Vue2.x的 provide、inject一样的,但是Vue3新特性这俩方法只能在setup中使用。
· Provide:接收2个参数,第一个key值,第二个value值,进行传递。
· Inject:接收2个参数,第一个是provide的key值,默认第二个参数可选,可以设置默认值(当找不到key值,设置一个默认值)。
2.App.vue
3.test.vue
4.Refs
该方法相当于Vue2.x的refs一样获取元素,那么在setup中配合使用ref对象进行获取。
5.isReadonly
用于检测该数据是不是可读数据,返回一个Boolean类型。
6.isRef
用于检测该数据是不是ref响应式数据,返回一个Boolean类型。
7.isReactive
用于检测该数据是不是reacttive响应式数据,返回一个Boolean类型。
八、Vue3的Diff优化
1、事件缓存
将事件缓存在_cache数组里面,可以理解为变成静态的。
比如这样一个有点击事件的按钮:
来看下在 Vue3 被编译后的结果:
注意看,onClick 会先读取缓存,如果没有缓存,便把传入的事件存到缓存里,都可以理解为变成静态节点,而在 Vue2 中就没有缓存,就是动态的。
2.添加静态标记与静态提升
看一下静态标记是什么, 源码地址:packages/shared/src/patchFlags.ts。
先了解一下静态标记有什么作用,在什么地方能用到。比如下面这样的代码:
在 Vue2 中编译的结果是,感兴趣的可以自行安装 vue-template-compiler 自行测试。
在 Vue3 中编译的结果是这样的:
看到上面编译结果中出现的 -1 和 1 ,这就是静态标记,这在 Vue2 中是没有的,patch 过程中就会判断这个标记来 Diff 优化流程,跳过一些静态节点对比。
在 Vue3 中会把这个不参与更新的元素保存起来,只创建一次,之后在每次渲染的时候不停地复用,比如上面例子中的这个,静态的创建一次保存起来。
3.patchKeyedChildren
在Vue2里updateChildren会进行:
· 头和头比
· 尾和尾比
· 头和尾比
· 尾和头比
· 都没有命中的对比
在 Vue3里patchKeyedChildren为:
· 头和头比
· 尾和尾比
· 基于最长递增子序列进行移动/添加/删除
看个例子,比如:
·老的 children:[ a, b, c, d, e, f, g ]
· 新的 children:[ a, b, f, c, d, e, h, g ]
先进行头和头比,发现不同便结束循环得到 [ a, b ] 再进行尾和尾比,发现不同便结束循环得到 [ g ] 再保存没有比较过的节点 [ f, c, d, e, h ],通过newIndexToOldIndexMap拿到在数组里对应的下标,生成数组 [ 5, 2, 3, 4, -1 ],-1是老数组里没有的就说明是新增 然后再拿取出数组里的最长递增子序列,也就是[ 2, 3, 4 ]对应的节点[ c, d, e ] 然后只需要把其他剩余的节点,基于[ c, d, e ]的位置进行移动/新增/删除便可以了。
使用最长递增子序列可以最大程度的减少 DOM 的移动,达到最少的 DOM 操作。