目录

  • 一、背景
  • 二、什么是组合式API(Composition API )
  • 组合式API全景
  • 为什么要引入组合式API
    • `mixins` 的方式
    • 域插槽的方式
    • 组合式API的方式
    • 结论
  • 组合式API存在的问题
  • 组合式API 的 script setup 语法糖
    • 顶层的绑定会被暴露给模板
    • 使用 `this`
    • steup中的生命周期钩子(对比 `Options API`)
  • 扩展
    • vite项目实现vue3函数和组件库的自动按需导入
  • 项目地址
  • 参考文档

一、背景

Vue3.x 版本的出现带来了许多令人眼前一亮的新特性,其中组合式 API(Composition API),一组附加的、基于功能的 API 被作为一种新的逻辑复用和代码组织的方式提供给了开发者,提供更加灵活的组合组件逻辑能力。

二、什么是组合式API(Composition API )

  • 组合式 API:一组低侵入式的、函数式的 API,使得我们能够更灵活地「组合」组件的逻辑
  • 用一句通俗的话来说:composition API 其实是用于解决功能、数据和业务逻辑分散的问题,使项目更益于模块化开发以及后期维护

先看一段简单的代码:

<template><h2>组合式API</h2><el-button type="primary" @click="increment">Count is: {{ state.count }}, double is: {{ state.double }}</el-button><div style="display: block;margin-top: 50px;"><router-link to="/" style="margin-top: 50px">首页</router-link></div>
</template><script>
import {computed, reactive} from "vue"export default {setup() {const state = reactive({count: 0,double: computed(() => state.count * 2)})function increment() {state.count++}return {state,increment}}
}
</script>

我们先来看下这段代码发生了啥?

import {computed, reactive} from "vue";

Component API 是以函数的形式展示组件属性,所以第一步就是导入我们需要的函数。在我们的例子中,我们用 reactive 创建响应属性,用 computed 创建计算属性。

export default {setup() {// ...return {state,increment}}

还有一个 setup 函数, setup 函数是一个新的组件选项。作为在组件内使用 Composition API 的入口点,如果 setup 返回一个对象,则对象的属性将会被合并到组件模板的渲染上下文,我们就可以在模板里使用对应的属性和方法。

组合式API全景

组合式 API 的使用,官方参考文档和 API 文档有详细说明,这里不过多说明。为方便大家理解和把握,根据官方的 API 文档整理了全景图。

Vue 组合式API 可以分为五大块:

  1. 数据响应(复杂对象):响应性基础API ,支持复杂对象 ObjectArray 的数据响应
  2. 数据响应(内部值):内部值指 JS内置的简单数据结构,包括 StringNumber
  3. computedwatch:基于响应式数据的数据计算与监听
  4. 生命周期:对原生命周期封装,例如:onMountedonBeforeMount
  5. 其他 API:重要支持性 API

为什么要引入组合式API

在 Vue2 中我们采用 Options API 来写上面的代码:

<template><h2>Option API</h2><el-button type="primary" @click="increment">Count is: {{ count }}, double is: {{ double }}</el-button><div style="display: block;margin-top: 50px;"><router-link to="/" style="margin-top: 50px">首页</router-link></div>
</template><script>
export default {data() {return {count: 0}},computed: {double() {return this.count * 2}},methods: {increment() {this.count++}}
}
</script>

那在 Vue2 中如果我们要复用这个逻辑,我们可以通过诸如 mixins 或作用域插槽的模式达成。

mixins 的方式

<template><h2>Option API Mixins</h2><el-button type="primary" @click="increment">Count is: {{ count }}, double is: {{ double }}</el-button><div style="display: block;margin-top: 50px;"><router-link to="/" style="margin-top: 50px">首页</router-link></div>
</template><script>
import CounterMixin from '@/mixins/counter'
export default {mixins: [CounterMixin]
}
</script>

mixins 存在的问题是:

  1. 渲染上下文中暴露的 property 来源不清晰。例如在阅读一个运用了多个 mixin 的组件代码时,很难看出某个 property 是从哪一个 mixin 中注入的。
  2. 命名空间冲突。mixin 之间的 property 和方法可能有冲突。

域插槽的方式

<template><h2>Option API Slot</h2><Counter v-slot="{ count, double, increment }"><el-button type="primary" @click="increment">Count is: {{ count }}, double is: {{ double }}</el-button></Counter><div style="display: block;margin-top: 50px;"><router-link to="/" style="margin-top: 50px">首页</router-link></div>
</template><script>
import Counter from '@/components/Counter'
export default {components: {Counter}
}
</script>

优点:有了scoped slots,我们就可以通过v-slot属性准确地知道我们可以访问哪些属性,这样就更容易理解代码了。
缺点:我们只能在模板中访问,而且只能在 Counter 组件作用域中使用。

组合式API的方式

useCounter.js

// 将这部分代码逻辑抽离出来
import {computed, reactive} from "vue"export function useCounter() {const state = reactive({count: 0,double: computed(() => state.count * 2)});const increment = function() { state.count++ }return {state,increment}
}

CounterSetup.vue

<template><h2>组合式API script setup 语法糖</h2><el-button type="primary" @click="increment">Count is: {{ state.count }}, double is: {{ state.double }}</el-button><div style="display: block;margin-top: 50px;"><router-link to="/" style="margin-top: 50px">首页</router-link></div>
</template><script setup>
import { useCounter } from '@/libs/useCounter'
const { state, increment } = useCounter()
</script>

是不是更加优雅了,相比较而言:

  1. 暴露给模板的 property 来源十分清晰,因为它们都是被组合逻辑函数返回的值。
  2. 不存在命名空间冲突,可以通过解构任意命名
  3. 不再需要仅为逻辑复用而创建组件实例
  4. 仅依赖它的参数和 Vue 全局导出的 API,而不是依赖其微妙的 this 上下文

结论

除了方便逻辑提取与复用之外,Composition API 带给我们的实际上更多的是一种新的代码编写思维。

当要去理解一个组件时,我们更加关心的是“这个组件是要干什么” (即代码背后的意图) 而不是“这个组件用到了什么选项”。基于 Options API 撰写出来的代码自然采用了后者的表述方式,然而对前者的表述并不好。

Options API 选项的强行分离为展示背后的逻辑关注点设置了障碍。此外,在处理单个逻辑关注点时,我们必须不断地在选项代码块之间“跳转”,以找到与该关注点相关的部分。

比如上面的例子中,基于 Options API 的方式我们必须在 datacomputedmethods 三个选项中跳转,来完成这段逻辑。而通过 Composition API 的方式我们把相同逻辑关注点的代码并列在一起,形成了一个独立的逻辑函数。

组合式API存在的问题

当然 Composition API 的引入也存在一定的弊端。

组合式API 在代码组织方面提供了更多的灵活性,但它也需要开发人员更多地自我克制来 “正确地完成它”,组合式API 会让没有经验的新手编写出“面条代码”。

Options API 中实际上形成了一种强制的约定:

  • props 里面设置接收参数
  • data 里面设置变量
  • computed 里面设置计算属性
  • watch 里面设置监听属性
  • methods 里面设置事件方法

会发现 Options API 都约定了我们该在哪个位置做什么事,这在一定程度上也强制我们进行了代码分割。

现在用 Composition API,不再这么约定了,所以代码组织非常灵活,如果作为一个新手,或者不深入思考的码农,那么在逻辑越来越复杂的情况下,setup 代码量越来越多,同样 setup 里面的 return 越来越复杂,势必会落入“面条代码”地步。

组合式API 的 script setup 语法糖

<setup script> 就是vue3新出的一个语法糖,使用方法就是在 script 标签的后面加上一个 setup 修饰。

代码如下:

<template><h2>组合式API script setup 语法糖</h2><el-button type="primary" @click="increment">Count is: {{ state.count }}, double is: {{ state.double }}</el-button><div style="display: block;margin-top: 50px;"><router-link to="/" style="margin-top: 50px">首页</router-link></div>
</template><script setup>
import { useCounter } from '@/libs/useCounter'
const { state, increment } = useCounter()
</script>

优点:

  1. 自动注册组件
  2. 属性和方法无需返回
  3. 更简洁的代码
  4. 更好的运行时性能

顶层的绑定会被暴露给模板

当使用 <script setup> 的时候,任何在 <script setup> 声明的顶层的绑定 (包括变量,函数声明,以及 import 引入的内容) 都能在模板中直接使用:

<template><div @click="log">{{ msg }}</div><div>{{ capitalize('hello') }}</div>
</template>
<script setup>
// 引入
import { capitalize } from '@/libs/helpers'
// 变量
const msg = 'Hello!'
// 函数
function log() {console.log(msg)
}
</script>

使用 this

setup 中你应该避免使用 this,因为它不会找到组件实例。setup 的调用发生在 data propertycomputed propertymethods 被解析之前,所以它们无法在 setup 中被获取。这使得 setup 在和其它 Options API 一起使用时可能会导致混淆。

steup中的生命周期钩子(对比 Options API

扩展

vite项目实现vue3函数和组件库的自动按需导入

在一个vue3项目中,我们经常需要从 vuevue-router等引入相应的函数方法进单个文件中。

比如:

import {  ref,  reactive,  toRefs,  watchEffect,  computed,  watch,  onUnmounted,} from 'vue'
import { useRouter } from 'vue-router'

这时我们可以使用基于unplugin项目的两个插件:

  • unplugin-auto-import 来实现vue函数的自动导入
  • unplugin-vue-components 来实现vue组件库的自动按需导入
  1. 首先在项目中安装这两个插件
yarn add unplugin-auto-import unplugin-vue-components -D
  1. 然后在 vite.config.js 中配置
// vite.config.js
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'export default defineConfig({plugins: [vue(),AutoImport({resolvers: [ElementPlusResolver()], // 这里使用ElementPlus组件库imports: ['vue','vue-router',{vuex: ['useStore']}]}),Components({resolvers: [ElementPlusResolver()]}),]
})

配置完成后我们就可以直接在项目中这样使用

<template><!--el-button 无需从 Element Plus 中导入--><el-button type="primary">{{ text }}</el-button><br><div style="display: block;margin-top: 50px;"><router-link to="/" style="margin-top: 50px">首页</router-link></div>
</template>
<script setup>const text = ref('我是一个 Element Plus 按钮')  // ref 无需从vue中导入
</script>

项目地址

本文所有代码地址:
gitlab(需要注册):https://gitlab.explorexd.com/devs/vue3-demo
github:https://github.com/jiaxudonggit/vue3-demo

参考文档

https://v3.cn.vuejs.org/guide/introduction.html
https://juejin.cn/post/7027443242928979982
https://juejin.cn/post/6844904191928827912
https://juejin.cn/post/7025837638540066824
https://element-plus.gitee.io/zh-CN/guide/installation.html
https://cn.vitejs.dev/guide/#scaffolding-your-first-vite-project

Vue3 组合式API初体验相关推荐

  1. Vue3通透教程【四】Vue3组合API初体验

    文章目录

  2. ap接口 php_小白php API初体验 php api文档 php api接口开发 php web ap

    这里的php 写API其实就是指提供一个WebServiceWebSite : 1.以html格式响应返回 2.由用户通过浏览器来接入 WebService : 1.以json/Xml格式返回 2.由 ...

  3. vue3组合式api基础(常用)

    vue3组合式api基础(常用) 前言:vue3中尽量不要使用'this',最好使用组合式api(Composition API),如果使用uni-app的,vue3只支持ios>=10(201 ...

  4. Vue3组合式Api script setup模式中顶层使用await报Top-level ‘await‘ expressions are only allowed when the ‘module‘

    今天练习Vue3的Suspense组件的时候碰到在Vue3组合式Api script setup模式中顶层使用await时报错Eslint错误(能正常编译),错误提示是: Top-level 'awa ...

  5. Vue2选项式API和Vue3组合式API的区别

    文章目录 Vue2选项式API和Vue3组合式API的区别 响应式处理 组件生命周期 组件通讯 其他差异 编译器的变化 TypeScript 静态类型提升 Vue2选项式API与Vue3组合式API ...

  6. vue3组合式api

    文章目录 组合式API介绍 什么是组合式 API? 为什么要有组合式 API? 更好的逻辑复用 更灵活的代码组织 Option Api Option Api的缺陷 Composition Api 更好 ...

  7. 谈谈vue3组合式api的优势

    vue2: options API 配置式 使用传统Options API(配置式API)中,新增或者修改一个需求,就需要分别在data,methods,computed里修改 . vue3: com ...

  8. 关于Vue3组合式API(Composition API)的个人理解

    首先,关于组合式API现已有众多大佬发布了相关介绍及相关教程,但是个人在学习过程中还是花了比较多的时间去理解 " 组合式API " 这个概念. 因为目前搜索引擎排的比较前面的文章其 ...

  9. Vue3 -- 组合式API

    组合式API 组合式api(Composition API)算是vue3对我们开发者来说非常有价值的一个api更新,我们先不关注具体语法,先对它有一个大的感知 1. composition vs op ...

最新文章

  1. 顺序结构,判断结构 if,switch
  2. 职场的你,如何《赢》?
  3. ASP+Access中文乱码的解决方法,ASP中文乱码,asp乱码问题
  4. python3 异步 semaphore 信号量 控制并发
  5. java url 生成图片_JAVA 通过URL生成水印图
  6. 怎么彻底重装清空电脑_笔记本电脑怎么重装系统Win7?20分钟完成系统重装,有可能吗?...
  7. SAP Commerce的Site列表
  8. [密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第10篇]RSA和强RSA问题有什么区别
  9. hadoop备战:hbase的分布式安装经验
  10. 链串实现功能(初始化、判断空串、串的赋值、串的连接、获取子串)
  11. 如何通过C#开发一个媒体播放器(中)
  12. WinForm开发(28)——TextBox(2)——Winform给TextBox设置默认值(获取焦点后默认值消失)
  13. Golang常量无法取地址
  14. 在互联网创业公司工作五年是一种怎样的体验?
  15. 实用帖!推荐一个无版权、免费、高清图片素材网站!
  16. 连接 s3.amazonaws.com port 443: Connection refused
  17. 使用qq 、微信和新浪微博三种方式登录demo
  18. 本地测试如何让token在有效内过期方法
  19. 新能源造车的恒大创新样本
  20. Linux---------安装以及基本语法知识

热门文章

  1. 长周期行业-航运(1)-波罗的海指数高峰历史
  2. 拍证件照还去照相馆?支付宝新功能在家就能拍,你不会还不知道吧
  3. 旅行商的背包(二进制优化多重+0/1背包枚举体积))
  4. Python安装路径更改到其他盘
  5. 招商银行 招银网络科技电话面试
  6. 今日科技联播:AI助手智商测评Siri进步最大,无人驾驶打车美国试行你可敢坐?...
  7. AI和机器学习对量化交易领域的影响
  8. 为什么X-scan扫描不到主机??
  9. 鹤望兰GSC DARLING in the FRANXX 到货评测
  10. ESXI挂载USB移动硬盘