vue3知识点

260 阅读2分钟

创建vue3项目

  1. Vue-CLI命令行工具 Vue-CLI版本要在 v4.5以上
$ npm install -g @vue/cli@next 
$ vue create my-project
  1. Vite 快速构建 vite是一个 web 开发构建工具,由于其原生 ES 模块导入方法,它允许快速提供代码。
$ npm init vite-app <project-name>
$ cd <project-name>
$ npm install
$ npm run dev

vue3新特性

屏幕快照 2021-09-10 上午9.45.49.png

Composition API

写一个组件,vue2.x的写法如下:

image.png 需要分别在选项(data、methods、computed...) 中处理逻辑,当我们增加一个需求,逻辑关注点的列表也会增长

image.png 当组件越复杂代码越长,就会越碎片化使得理解和维护组件变得困难。另外,在处理单个逻辑关注点时,我们必须不断地“跳转”相关代码的选项块。

如果将同一个逻辑关注点相关的代码配置在一起,按照逻辑进行分割,就会使代码可读性和可维护性都更高。这就是组合式 API解决的

image.png

vue2.x 版本给出的解决方案就是 Mixin, Mixin会出现以下问题

  • 命名冲突问题
  • 不清楚暴露出来的变量的作用
  • 逻辑重用到其他 component 经常遇到问题
1、Setup

在创建组件之前执行,一旦 props 被解析,并充当合成 API 的入口点。

注意:setup是在 beforeCreate 之前执行这时还未创建组件实例,因此在 setup 选项中没有 this,也无法访问任何属性。

参数

  • props: 组件传入的属性
  • context
props

setup 函数中的 props 是响应式的,当传入新的 prop 时,prop将被更新

注意:props数据不能使用 ES6 解构,否则响应式数据失效 当既想使用es6解构,又要是响应式的,可以采用toRefs

context

不是响应式的,可以通过es6语法解构setup(props, {attrs, slots, emit})

  • attrs: 获取当前组件标签上所有没有通过props接收的属性的对象, 相当于 this.$attrs
  • slots: 包含所有传入的插槽内容的对象, 相当于this.$slots
  • emit: 用来分发自定义事件的函数, 相当于 this.$emit 注意:与 props 不同,attrs 和 slots 是响应式的如果你打算根据 attrs 或 slots 更改应用副作用,那么应该在 onUpdated 生命周期钩子中执行此操作
返回值

setup里返回一个对象,就可以在组件模板中渲染,否则值渲染无效

2、生命周期钩子

setup ()内部调用生命周期钩子:

注意:因为 setup 是围绕 beforeCreate 和 created 生命周期钩子运行的(setup代替了beforeCreatecreated),所以不需要显式地定义它们。

Vue2.x 中的beforeDestroy名称变更成beforeUnmountdestroyed 变更为 unmounted,为了更加语义化,

选项式 APIHook inside setup
beforeCreateNot needed*
createdNot needed*
beforeMountonBeforeMount
mountedonMounted
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeUnmountonBeforeUnmount
unmountedonUnmounted
errorCapturedonErrorCaptured
renderTrackedonRenderTracked
renderTriggeredonRenderTriggered
activatedonActivated
deactivatedonDeactivated
3、Ref、Reactive、toRefs

Ref、Reactive使声明的变量变成响应式的,在任何地方都生效

不同:

ref主要声明基本数据类型;reactive主要声明对象;

ref也可以用在对象上,但是没有reactive具有高度的响应式,reactive返回的对象是一个深层递归转换的proxy对象

toRefs 将响应式对象转换为普通对象用于将一个 reactive 对象转化为属性全部为 ref 对象的普通对象

import { ref, reactive, toRefs} from 'vue'

const counter = ref(0)
const state = reactive({
      foo: 1,
      bar: 2
    })
const stateAsRefs = toRefs(state)
// ref 和 原始property “链接”
state.foo++
console.log(stateAsRefs.foo.value) // 2

stateAsRefs.foo.value++
console.log(state.foo) // 3
4、watch、watchEffect、computed的用法
watch

参数

  • source: 可以支持 string,Object,Function,Array; 用于指定要侦听的响应式变量
  • callback: 执行的回调函数
  • options:支持 deep、immediate 和 flush 选项。(flush:post/sync如果需要在组件更新重新运行侦听器副作用)

watch 函数用来侦听特定的数据源,并在回调函数中执行副作用。默认情况是惰性的,也就是说仅在侦听的源数据变更时才执行回调。默认情况下,watch 是惰性的,immediate: true可以立即执行回调函数,deep:true可以深度监听。

watchEffect
  1. 不需要手动传入依赖
  2. 默认初始时就会执行第一次, 从而可以收集需要监视的数据
  3. 无法获取到变化前的值, 只能获取变化后的值
computed
  • 直接创建计算值
  • 接受 getter 函数并为 getter 返回的值返回一个不可变的响应式ref对象

Teleport(瞬移或者传送门)

将模板移动到 DOM 中 Vue app 之外的其他位置的技术, 主要处理嵌套组件的定位、z-index 和样式的问题。

留意 to 属性跟上面的 id 选择器一致,disabled禁止移动

<teleport to="#some-id" />
<teleport to=".some-class" />
<teleport to="[data-teleport]" />

Suspense

主要用于在进行一个异步加载时,可以先提供一些静态组件作为显示内容,然后当异步加载完毕时再显示.

<template> 
  <div> 
    <div v-if="!loading"> ... </div> 
    <div v-if="loading"> 加载中... </div> 
  </div> 
</template>

上面这种事通过v-if来动态展示loading

使用Suspense就会简单很多,如下图:

#default插槽里面的内容就是你需要渲染的异步组件; #fallback就是你指定的加载中的静态组件。

注意:AsyncComponent组件需要返回一个Promise

<Suspense> 
  <template #default> 
    <async-component></async-component>
  </template> 
  <template #fallback> 
    <div> Loading... </div> 
  </template> 
</Suspense>

Fragment

在 Vue2.x 中, template中只允许有一个根节点:

<template>
  <div>
     <span></span>
     <span></span>
  </div>
</template>
复制代码

但是在 Vue3.x 中,你可以直接写多个根节点, 是不是很爽:

<template>
  <span></span>
  <span></span>
</template>

变更

v-model升级

  • 非兼容:用于自定义组件时,v-model prop 和事件默认名称已更改:

    • prop:value -> modelValue
    • event:input -> update:modelValue
  • 非兼容v-bind 的 .sync 修饰符和组件的 model 选项已移除,可用 v-model 作为代替;

  • 新增:现在可以在同一个组件上使用多个 v-model 进行双向绑定;

  • 新增:现在可以自定义 v-model 修饰符

vue3的双向绑定

<modal v-model="isVisible"></modal>
<!-- 相当于 --> 
<modal :modelValue="isVisible" @update:modelValue="isVisible = $event"></modal>

如果要绑定属性名, 只需要给v-model传递一个参数就行, 同时可以绑定多个v-model

<modal v-model:visible="isVisible" v-model:content="content"></modal> 
<!-- 相当于 --> 
<modal :visible="isVisible" :content="content" @update:visible="isVisible" @update:content="content" />

Slot 统一

在 Vue2.x 中具名插槽和作用域插槽分别使用slotslot-scope来实现, 在 Vue3.0 中将slotslot-scope进行了合并同意使用。 Vue3.0 中v-slot

<template v-slot:content="scoped"> 
  <div v-for="item in scoped.data">{{item}}</div> </template>
<!-- 也可以简写成: --> 
<template #content="{data}"> 
  <div v-for="item in data">{{item}}</div>
</template>

全局 API

目前vue3的入口写法:

import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')

createApp返回一个应用实例,该实例初始化后,应用实例 app 可用于挂载具有 app.mount(domTarget)