banner
banner
banner
NEWS LETTER

VUE3-快速上手

Scroll down

vue概念

  • 用于构建用户界面的 JavaScript 框架–渐进式框架。
  • 基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型。

vue核心功能

  • 声明式渲染:拓展了模板语法,描述HTML跟js状态间的关系
  • 响应性:自动跟踪js状态并在发生变化时响应式的更新DOM

渐进式框架

  • 无需构建步骤,渐进式增强静态的 HTML
  • 在任何页面中作为 Web Components 嵌入
  • 单页应用 (SPA)
  • 全栈 / 服务端渲染 (SSR)
  • Jamstack / 静态站点生成 (SSG)
  • 开发桌面端、移动端、WebGL,甚至是命令行终端中的界面

API风格

  • 选项式 — 不适用构建工具/低复杂度

    • 包含多个选项的对象来描述组件的逻辑如,data、methods、mounted,选项中定义的属性都会暴露在函数内部的this,this指向当前组件实例
  • 组合式API — 完整单页面应用

    • 使用导入的API函数来描述组件逻辑。通常搭配<script setup>使用

vue3优点

  • 性能的提升
    • 打包大小减少41%
    • 初次渲染快55%, 更新渲染快133%
    • 内存减少54%
  • 源码的升级
    • 使用Proxy代替defineProperty实现响应式
    • 重写虚拟DOM的实现和Tree-Shaking
  • 拥抱TypeScript
  • 新的特性
    • Composition API(组合API)
      • setup配置
      • ref与reactive
      • watch与watchEffect
      • provide与inject
    • 新的内置组件
      • Fragment
      • Teleport
        • Suspense
    • 其他改变
      • 新的生命周期钩子
      • data 选项应始终被声明为一个函数
      • 移除keyCode支持作为 v-on 的修饰符

创建项目 + vite

  • vite
  • node版本要16以上
  • 使用create-vue
  • 安装:npm create vue@latest

模板语法

  • 文本插值:{{}}
  • 原始html:v-html=""
  • Attribute绑定:(v-bind:xxx="" 简写 :xxx="")
    • 正常情况:值为null或undefined,attribute将会从渲染的元素上移除
    • 布尔型:值为真值或一个空字符串,元素会包含这个attribute;为其他假值时忽略
    • 动态绑定多个值:对象包含多个属性。使用不带参的v-bind,绑定到单个元素上。
      • v-bind=”obj”
  • 支持javascript表达式或者调用函数

指令(Directives)

  • 期望值为一个javascript表达式,表达式的值变化时响应式更新DOM
  • javascript表达式使用v-bind(:),函数使用v-on(@)
  • 参数::xxx=""
  • 动态参数::[字符串或null]=""
    • 三限制:禁空格、禁引号、禁大写
  • 修饰符.: 触发事件

响应式原理

常用 Composition API

setup

  • 代表使用组合式API,<script setup>是setup函数的语法糖
  • <script setup>获取props,emit,context
    • 子组件引入import { useContext, defineProps, defineEmit } from ‘vue’
    • emit
      • 定义:const emit = defineEmit(['父组件在子组件标签上传的事件名'])
      • 在子组件的某个事件触发:emit(‘事件名’, 子组件传递的数据),父组件通过事件参数拿到
    • ctxconst ctx = useContext()
    • propsconst props = defineProps({ 父组件在子组件标签上传的属性名: 该属性的类型 })
  • 注意点:
    • setup执行的时机
      • 在beforeCreate之前执行一次,this是undefined。
    • setup的参数
      • props:值为对象,包含:组件外部传递过来,且组件内部声明接收了的属性
      • context:上下文对象
        • attrs:值为对象,包含:组件外部传递过来,但没有在props配置中声明的属性, 相当于this.$attrs
        • slots:收到的插槽内容, 相当于 this.$slots
        • emit:分发自定义事件的函数, 相当于 this.$emit

ref函数

  • 作用: 声明一个响应式的状态
  • 使用:引入import { ref } from ‘vue’
  • 语法: const xxx = ref(initValue)
    • JS中操作数据:xxx.value
    • 模板中读取数据: 不需要.value,直接:<div>{{xxx}}</div>
  • 优点:
    • 深层响应性
      • 应用于任意值,即改变就会检测
      • shallow ref 可放弃深层响应性
      • 非原始值将通过 reactive() 转换为响应式代理
    • DOM更新时机
      • 更改响应式状态后,DOM会自动更新,但并不是同步
      • 等待一个状态改变后的DOM更新完成,使用nextTick()
  • 备注:
    • 接收的数据可以是:基本类型、也可以是对象类型。
    • 基本类型的数据:响应式依然是靠Object.defineProperty()的get与set完成的。
    • 对象类型的数据:使用reactive处理

reactive函数

  • 作用: 定义一个对象类型的响应式数据,返回一个代理对象(Proxy的实例对象,简称proxy对象)
  • 语法:const 代理对象= reactive(源对象)接收一个对象(或数组)
  • 使用:代理对象
  • 局限性:只能用于对象类型(对象、数组和Map、Set这样的集合类型),并且不能替换整个对象,解构不友好
  • 内部基于 ES6 的 Proxy 实现,通过代理对象操作源对象内部数据进行操作。

reactive 和 ref 区别

  • 从定义数据角度对比
    • ref用来定义:基本类型数据
    • reactive用来定义:对象(或数组)类型数据
    • 注:ref也可以定义对象(或数组)类型数据, 它内部会自动通过reactive转为代理对象
  • 从原理角度对比
    • ref通过Object.defineProperty()的get与set来实现响应式(数据劫持)
    • reactive通过使用Proxy来实现响应式(数据劫持), 并通过Reflect操作源对象内部的数据
  • 从使用角度对比
    • ref定义的数据:操作数据需要.value,读取数据时模板中直接读取不需要.value
    • reactive定义的数据:操作数据与读取数据:均不需要.value

⭐ 计算属性computed — 依赖响应式状态的复杂逻辑

  • 与Vue2中computed配置功能一致☞VUE2-基础(主了解)
  • 计算属性值会基于其响应式依赖被缓存,只有依赖改变才会去重新计算
  • 写法:
    • 引入钩子:import { computed } from ‘vue’
    • 使用:computed(()=> {})

侦听器 watch — 在状态变化时执行一些“副作用”

  • 与Vue2中watch配置功能一致☞VUE2-基础(主了解)

  • 两个小“坑”:

    • 监视reactive定义的响应式数据时:oldValue无法正确获取、强制开启了深度监视(deep配置失效)
    • 监视reactive定义的响应式数据中某个属性时:deep配置有效
  • 写法:

    • 引入钩子:import { watch } from ‘vue’
    • 基本使用:watch(变量,(newValue,oldValue)=>{},{immediate:true})
    • 监视多个ref定义的响应式数据
      • watch([变量1,变量2],(newValue,oldValue)=>{})
    • 监视reactive定义的响应式数据中的某个属性(监视的是对象中的某个属性,所以deep配置有效)
      • watch(()=>对象.属性,(newValue,oldValue)=>{},{immediate:true,deep:true})
    • 监视reactive定义的响应式数据中的多个属性
      • watch([()=>对象.属性,()=>对象.属性2],(newValue,oldValue)=>{},{immediate:true,deep:true})
  • 深层侦听器

    • 使用 deep: true 开启,开销很大,无必要不使用
  • 即时回调的侦听器

    • 使用 immediate: true 开启
  • watchEffect函数

    • watch的套路是:既要指明监视的属性,也要指明监视的回调。
    • watchEffect的套路是:不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性
    • 使用:watchEffect(()=>{})
    • 注:仅会在其同步执行期间,才追踪依赖。在使用异步回调时,只有在第一个 await 正常工作前访问到的属性才会被追踪。
  • 回调的触发时机

    • 默认,用户创建的侦听器回调,都会在Vue 组件更新前被调用
    • 在侦听器回调中能访问被 Vue 更新之后的 DOM,指明 flush: ‘post’ 选项
  • 停止侦听器

    • 场景:用异步回调创建一个侦听器,它不会绑定到当前组件上,必须手动停止它,以防内存泄漏
    • 停止一个侦听器:调用 watch 或 watchEffect 返回的函数
      • const unwatch = watchEffect(() => {})
      • unwatch()

⭐ 生命周期钩子

vue生命周期钩子

  • Vue3可继续使用Vue2的生命周期钩子,但有两个更名:
    • beforeDestroy 改名为 beforeUnmount
    • destroyed 改名为 unmounted
  • Vue3的Composition API 形式的生命周期钩子,与Vue2中钩子对应关系如下:(vue3:vue2)

    • beforeCreate ==>setup()
    • created ==>setup()
    • beforeMount ==>onBeforeMount
    • mounted ==>onMounted
    • beforeUpdate ==>onBeforeUpdate
    • updated ==>onUpdated
    • beforeUnmount ==>onBeforeUnmount
    • unmounted ==>onUnmounted
  • vue3生命周期钩子的作用

    • beforeCreate

      • 在组件实例初始化完成后立即调用,data() 和 computed 等选项处理之前立即调用
    • created

      • 已完成响应式数据、计算属性、方法和侦听器。
      • 然而,此时挂载阶段还未开始,因此 $el 属性仍不可用
    • beforeMount

      • 在组件被挂载之前调用,还没创建DOM节点
    • mounted

      • 在组件挂载之后调用,所有同步子组件都已经被挂载。
      • 其自身的 DOM 树已经创建完成并插入了父容器中。
      • 处理副作用
    • beforeUpdate

      • 在组件即将因为一个响应式状态变更而更新其DOM树之前调用。
      • 在 Vue 更新 DOM 之前访问 DOM 状态
    • update

      • 在组件因为一个响应式状态变更而更新其 DOM 树之后调用。
      • 父组件的更新钩子将在其子组件的更新钩子之后调用。
      • 在组件的任意 DOM 更新后被调用
    • beforeUnmount

      • 在一个组件实例被卸载之前调用
      • 当这个钩子被调用时,组件实例依然还保有全部的功能
    • unmounted

      • 在一个组件实例被卸载之后调用,
      • 可以在这个钩子中手动清理一些副作用,例如计时器、DOM 事件监听器或者与服务器的连接。
    • activated

      • 组件实例是 <KeepAlive> 缓存树的一部分,当组件被插入到 DOM 中时调用
    • deactivated

      • 组件实例是 <KeepAlive> 缓存树的一部分,当组件从 DOM 中被移除时调用

模板引用

  • ref:直接访问底层DOM元素,DOM 元素或子组件实例被挂载后,可以直接引用
  • 使用:
    • 引入:import { ref, onMounted } from ‘vue’
    • 使用:<view ref="" />
  • v-for中的模板引用:

    • ref的值是数组
    • ref 数组并不保证与源数组相同的顺序
  • 函数模板引用:

    • :ref绑定为一个函数,函数会收到元素引用作为其第一个参数
      • <input :ref="(el) => {}"/>
  • 组件上的ref:

    • 用在组件上获取的是组件实例

其它 Composition API

shallowReactive 与 shallowRef

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

readonly 与 shallowReadonly

  • readonly: 让一个响应式数据变为只读的(深只读)
  • shallowReadonly:让一个响应式数据变为只读的(浅只读)
  • 应用场景: 不希望数据被修改时。

toRaw 与 markRaw

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

customRef

  • 作用:创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制
  • 实现防抖效果:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    <template>
    <input type="text" v-model="keyword">
    <h3>{{keyword}}</h3>
    </template>

    <script>
    import {ref,customRef} from 'vue'
    export default {
    name:'Demo',
    setup(){
    //自定义一个myRef
    function myRef(value,delay){
    let timer
    //通过customRef去实现自定义
    return customRef((track,trigger)=>{
    return{
    get(){
    track() //告诉Vue这个value值是需要被“追踪”的
    return value
    },
    set(newValue){
    clearTimeout(timer)
    timer = setTimeout(()=>{
    value = newValue
    trigger() //告诉Vue去更新界面
    },delay)
    }
    }
    })
    }
    let keyword = myRef('hello',500) //使用程序员自定义的ref
    return { keyword }
    }
    }
    </script>

provide 与 inject

  • 作用:实现祖先与后代组件间通信
  • 套路:父组件有一个 provide 选项来提供数据,后代组件有一个 inject 选项来开始使用这些数据
  • 具体写法:
    1. 祖组件中:使用provide(‘通信的别名’,要传递的变量)
    2. 后代组件中:const 得到的变量 = inject(‘通信的别名’)

响应式API:工具函数

  • isRef(): 检查一个值是否为一个 ref 对象
  • unref(): 如果参数是 ref,则返回内部值,否则返回参数本身
  • isReactive(): 检查一个对象是否是由 reactive 创建的响应式代理
  • isReadonly(): 检查一个对象是否是由 readonly 创建的只读代理
  • isProxy(): 检查一个对象是否是由 reactive 或者 readonly 方法创建的代理
  • toRef():创建一个 ref 对象,其value值指向另一个对象中的某个属性。
    • 语法:const name = toRef(person,’name’)
  • toRefs(): 与toRef功能一致,值指向一个对象
    • 语法:toRefs(person)

新的组件

Fragment

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

Teleport

  • 定义: 将组件html结构移动到指定位置的技术
  • 使用:teleport标签包裹的内容是移动的内容,标签上指定to=”移动位置”

Suspense

  • 等待异步组件时渲染一些额外内容
  • 使用步骤:
    • 引入钩子:import {defineAsyncComponent} from ‘vue’
    • 异步引入组件:const 组件名 = defineAsyncComponent(()=>import(‘组件路径’))
      • 使用Suspense包裹组件,并配置好对应插槽的内容

其他

全局API的转移

  • Vue 2 有许多全局 API 和配置在vue3中调整。
    • 将全局的API,即:Vue.xxx调整到应用实例(app)上
      全局 API 实例 API (app)
      Vue.config.xxxx app.config.xxxx
      Vue.config.productionTip 移除
      Vue.component app.component
      Vue.directive app.directive
      Vue.mixin app.mixin
      Vue.use app.use
      Vue.prototype app.config.globalProperties

其他改变

  • data选项应始终被声明为一个函数。
  • 过度类名的更改:.v-enter-from,.v-leave-to(vue3写法)
  • 移除keyCode作为 v-on 的修饰符,同时也不再支持config.keyCodes
  • 移除v-on.native修饰符
  • 移除过滤器(filter)
其他文章
cover
VUE3-路由
  • 24/11/01
  • 14:39
  • VUE
cover
VUE3-Pinia
  • 24/11/01
  • 14:39
  • VUE
目录导航 置顶
  1. 1. vue概念
  2. 2. vue核心功能
  3. 3. 渐进式框架
  4. 4. API风格
    1. 4.1. 选项式 — 不适用构建工具/低复杂度
    2. 4.2. 组合式API — 完整单页面应用
  5. 5. vue3优点
  6. 6. 创建项目 + vite
  7. 7. 模板语法
  8. 8. 指令(Directives)
  9. 9. 响应式原理
  10. 10. 常用 Composition API
    1. 10.1. setup
    2. 10.2. ref函数
    3. 10.3. reactive函数
    4. 10.4. reactive 和 ref 区别
    5. 10.5. ⭐ 计算属性computed — 依赖响应式状态的复杂逻辑
    6. 10.6. 侦听器 watch — 在状态变化时执行一些“副作用”
    7. 10.7. 深层侦听器
    8. 10.8. 即时回调的侦听器
    9. 10.9. watchEffect函数
    10. 10.10. 回调的触发时机
    11. 10.11. 停止侦听器
  11. 11. ⭐ 生命周期钩子
    1. 11.1. Vue3的Composition API 形式的生命周期钩子,与Vue2中钩子对应关系如下:(vue3:vue2)
    2. 11.2. vue3生命周期钩子的作用
    3. 11.3. beforeCreate
    4. 11.4. created
    5. 11.5. beforeMount
    6. 11.6. mounted
    7. 11.7. beforeUpdate
    8. 11.8. update
    9. 11.9. beforeUnmount
    10. 11.10. unmounted
    11. 11.11. activated
    12. 11.12. deactivated
  12. 12. 模板引用
    1. 12.1. v-for中的模板引用:
    2. 12.2. 函数模板引用:
    3. 12.3. 组件上的ref:
  13. 13. 其它 Composition API
    1. 13.1. shallowReactive 与 shallowRef
    2. 13.2. readonly 与 shallowReadonly
    3. 13.3. toRaw 与 markRaw
    4. 13.4. customRef
    5. 13.5. provide 与 inject
    6. 13.6. 响应式API:工具函数
  14. 14. 新的组件
    1. 14.1. Fragment
    2. 14.2. Teleport
    3. 14.3. Suspense
  15. 15. 其他
    1. 15.1. 全局API的转移
    2. 15.2. 其他改变
请输入关键词进行搜索