Vue3.0 重学

368 阅读7分钟

这是我参与更文挑战的第24天,活动详情查看: 更文挑战

1,环境搭建

​ 1, CDN引入最新的vue3

 <script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.11/vue.global.prod.js"></script>

​ 2, 升级vue-cli 升级到v4.5版本以上

 npm i -g @vue/cli@next

-注意事项:最好提前卸载掉之前的版本,不然使用的时候,很有可能还是vue2, 最好的办法就是卸载完之后重启一下, 升级完之后,查看版本:

 vue -V    > 4.5版本以上即可
​ vue create vue-cli-test
​ npm run serve
​ 按向下的箭头

2,项目创建

通过vite创建

# 安装create-vite-app
​   npm install -g create-vite-app
# 通过vite-app创建vite-app-test的项目
​   npm init vite-app projectName  或者   create-vite-app projectName
​   npm install
​   npm run dev

3,Vue3新特性总结

**(1)V3.0 六大亮点 **

- Performance: 性能比Vue2.0快1~2倍

- Three shaking support: 按需编译,体积比Vue2更快

- Composition API: 组合API,(类型React Hooks)

- Better TypeScript support: 更好的支持TS

- Custom Renderer API: 暴露了自定义渲染API

- Fragment, Teleport, Suspense: 更先进的组件

**(2)V3.0 是如何实现变快的 **

(1)Vue2中的虚拟dom进行全量的对比
  
(2)Vue3新增 了静态标记PatchFlag,在与上次虚拟dom节点进行对比的时候,只对比带有pathFlag的节点,并且可以
通过flag的信息得知当前节点要对比的具体的内容
  • hoistStatic 静态提升
(1) Vue2中无论元素是否参与更新,每次都会重新创建

(2) Vue3中对于不参与更新的元素,只会创建一次,之后会在每次渲染的时候被不停的复用
  • cacheHandlers 事件侦听器缓存
(1) 默认情况下onClick会被视为动态绑定,所以每次都会去追踪它的变化,但是因为是同一个函数,所以没有追踪变

化,直接缓存起来复用即可
  • SSR渲
(1) 当有大量静态的内容时候,这些内容会被当作纯字符串推荐一个buffer里面,即使粗在动态绑定,
    会通过模板插值嵌入进去,这样回避通过虚拟dom来渲染的快上很多很多

(2) 当静态内容大到一定量及时候,会用createStaticVNode方法在客户端

4,Composition API

  • setup() 函数是组合API的入口函数

  • 简单数据变量的声明:ref

  • 复杂数据变量的声明:reactive

(1) setup()执行时机

beforeCreate: 表示组件刚刚被创建出来,组件的data,methods还没有初始化好

setup()

Created: 表示组件刚刚被创建出来,并且组件的data,method已经初始化好

注意点:

1,由于在执行setup()函数的时候,还没有执行created生命周期的方法,所以在setup函数中,
  是无法使用data,和methods
 
2,由于我们无法在setup中使用data,methods,所以Vue为了避免我们错误的使用,直接把setup中的
  this修改成了undefined
  
3,setup只能是同步的,不能是异步的

(2) 什么是reactive?

  • reactive是Vue3.0中提供的实现响应数据的方法

  • Vue2.0中响应数据是通过defineProperty实现的

  • Vue3.0中响应数据是通过ES6中Proxy来实现的:一个响应式数据, Vue3的本质是将传入的数据包装成一个 Proxy对象

**reactive注意点: **

  1, 参数必须是一个对象(json/arr),如果想监听一个变量,vue3提供了ref.

​  2, 如果给reactive传递了其他对象,默认情况下修改对象,界面不会自动更新
      如果想更新,可以通过重新赋值的方式

(3) 什么是ref?

  • ref和reactive一样,也是用来实现响应式数据的方法

  • 由于reactive必须传递一个对象,导致开发中想让某个变量实现响应式就非常麻烦,所以vue3提供了ref,实现简单值得监听

  • ref的本质: ref的本质其实还是reactive

  • ref的原理其实也是自动把ref转换成reactive对象

      ref(18) => reative({value:18)
    

**注意点:**如果是通过ref创建的数据,在template中使用不用通过.value来获取,因为Vue会自动给我们添加.value

(4) ref 和 reactive的区别?

   1, 如果在template里面使用的是ref类型的数据,那么Vue会自动帮我们添加.value2, 如果在template里面使用的是reactive类型的数据,那么Vue不会自动帮我们添加.value3, Vue在解析数据之前,会自动判断这个数据是否是ref类型,若是自动添加.value, 
      如果不是就不自动添  加.value4, 怎么判断是ref类型,还是reactive类型,Vue3提供了一个私有属性__v_isRef : true

    或者 我们自己也可以判断:isRef(), isReactive()

(5)递归监听&&非递归监听

1, 默认情况:无论是ref还是reactive,都是递归监听,如果数据量很大,非常消耗性能

2, 只监听第一层,如果第一层变化了,页面就更新

​ 如果是ref类型: shallowRef, 如果是reactive类型: shallowReactive

本质:shallowReactive 只监听第一层数据变化,
     如果第一层数据变化了,整个UI都更新,
     如果第一层数据没有变化,UI不变
     如果是通过shallowRef 创建的数据,那么Vue监听的是.value变化,并不是第一层的变化
     如果只是想监听第几个变化,根据传递的做修改   triggerRef

3, 应用场景:

 一般情况下我们使用ref, reactive即可,只有在需要监听数据量比较大的时候,我们才使用shallowRef, shallowReactive

4, shallowRef, shallowReactive的本质:

 shallowRef(10) 底层还是-> shallowReactive({value:10}) 他监听的是.value的变化

(6)toRaw: 获取原始数据

​ 如果直接修改obj,那么无法触发页面更新,只有通过包装之后的对象来修改,才会触发界面更新

1, 如果是reactive包装的对象,获取原始对象:toRaw

2, 如果想通过toRaw拿到ref类型的数据,需要通过toRaw.value获取

3, 作用:ref/reactive数据类型的特点: 每次修改都会被追踪,都会更新UI界面,但是这样其实非常消耗性能的。

   所以如果我们有一些操作不需要追踪,不需要更新UI界面,那么这个时候,我们就可以通过toRaw获取到他的原始数
   据,对数据进行修改

(7)markRow 数据永远不被追踪

let obj = {name:'zlm', age: 19}
    obj = markRow(obj)
    let state = reactive(obj)

(8)ref和toRef的区别

1, ref 复制,修改响应式数据不会影响以前的数据

2, toRef 应用,修改响应式数据会影响以前的数据

3, ref: 数据发生变化,界面就回自动更新

4, toRef 数据发生变化,界面也不会自动更新

5, toRef应用场景: 如果想让响应式数据和以前的数据关联起来,并且更新响应式数据之后还不想更新UI,
  那么就可以使用toRef
  toRef(obj, 'name')

(9) toRefs

​ 如果是对象里面的多个属性都想实现响应式,可以用toRefs

  • customRef 自定义

    function myRef(value) {
      return customRef((track, trigger) => {
        return {
          get() {
            track() // 告诉Vue这个数据是需要追踪变化的
            return value
          },
          set(newValue) {
            value = newValue
            trigger() // 告诉Vue触发界面更新
          }
        }
      })
    }
    

5,技巧总结

1,获取元素DOM

ref.value

2,readyonly, isReadonly, shallowReadonly

readonly: 用于创建一个只读数据,并且是递归只读
shallowReadonly: 用于创建一个只读数据,但是不是递归只读,只有第一层只读
isReadonly: 判断是否是只读数据

3,Compositon API 和 Option API 可混合使用

 Compositon的本质: 声明了一个age, 它的本质是注入到data

4,Vue3响应式数据本质

vue2中是通过defineProperty来实现响应式数据

Vue3中是通过Proxy来实现响应式数据的