Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >vue3 -- 通过简单示例,聊一聊Composition API

vue3 -- 通过简单示例,聊一聊Composition API

原创
作者头像
奋飛
修改于 2020-12-09 02:20:36
修改于 2020-12-09 02:20:36
1.9K0
举报
文章被收录于专栏:Super 前端Super 前端

在 vue3 版本之前,我们复用组件(或者提取和重用多个组件之间的逻辑),通常有以下几种方式:

  • Mixin:命名空间冲突 & 渲染上下文中暴露的 property 来源不清晰。例如在阅读一个运用了多个 mixin 的模板时,很难看出某个 property 是从哪一个 mixin 中注入的。
  • Renderless Component:无渲染组件需要额外的有状态的组件实例,从而使得性能有所损耗
  • Vuex:就会变得更加复杂,需要去定义 Mutations 也需要去定义 Actions

上述提到的几种方式,也是我们项目中正在使用的方式。对于提取和重用多个组件之间的逻辑似乎并不简单。我们甚至采用了 extend 来做到最大化利用已有组件逻辑,因此使得代码逻辑依赖严重,难以阅读和理解。

Vue3 中的 Composition API 便是解决这一问题;且完美支持类型推导,不再是依靠一个简单的 this 上下文来暴露 property(比如 methods 选项下的函数的 this 是指向组件实例的,而不是这个 methods 对象)。其是一组低侵入式的、函数式的 API,使得我们能够更灵活地「组合」组件的逻辑。

使用 Vue2 和 Vue3 开发组件有很大的差异性:

  • Vue2 开发组件,我们往往通过选项类型组织代码;props => ui state => 事件
  • Vue3 Composition Api 开发组件,基于逻辑关注点组织代码;(响应式)参数 => 生命周期绑定 => 响应式数据(ref、reactive)

下面,通过一个示例代码,结合 Vue2 和 Vue3 来聊聊 Composition Api 。

代码语言:txt
AI代码解释
复制
<template>
  <div>
    <p>当前系统的主题色为 -- {{color}}</p>
    <p>当前viewport的宽高比为16:9 -- {{is16than9}}</p>
  </div>
</template>
composition-api.gif
composition-api.gif

WEB API

说明

示例

Window.matchMedia()

回一个新的MediaQueryList 对象,表示指定的媒体查询字符串解析后的结果

window.matchMedia(mediaQueryString)

prefers-color-scheme

检测用户是否有将系统的主题色设置为亮色或者暗色

window.matchMedia('(perfers-color-scheme: dark)')

aspect-ratio

可以用来测试 viewport 的宽高比

①:主题色相关 ②:宽高比检测相关

vue2 实现

代码语言:txt
AI代码解释
复制
export default {
    name: 'SystemColor',
    data () {
      return {
        color: '',	// ①
        is16than9: false	// ②
      }
    },
    methods: {
      // ①
      perfersColorSchemeUpdate () {
        this.perfersColorSchemeMedia = window.matchMedia('(perfers-color-scheme: dark)')
        this.color = this.perfersColorSchemeMedia.matches ? 'dark': 'light'
      },
      // ②
      aspectRatioUpdate () {
        this.aspectRatioMedia = window.matchMedia('(aspect-ratio: 16/9)')
        this.is16than9 =  this.aspectRatioMedia.matches
      }
    },
    created () {
      // ①
      this.perfersColorSchemeUpdate()
      this.perfersColorSchemeMedia.addEventListener('change', this.perfersColorSchemeUpdate)
			// ②
      this.aspectRatioUpdate()
      this.aspectRatioMedia.addEventListener('change', this.aspectRatioUpdate)
    },
    destroyed () {
      // ①
    	this.perfersColorSchemeMedia.removeEventListener('change', this.perfersColorSchemeUpdate)
      // ② 
      this.aspectRatioMedia.removeEventListener('change', this.aspectRatioUpdate)
    } 
}

现在的诉求,又有一个新组件我们需要复用 「主题色相关」内容,我们需要对其进行抽离。

在 vue2 中,我们优先想到的是采用 mixins 方式

代码语言:txt
AI代码解释
复制
/* perfersColorSchemeMixin.js */
export default {
  methods: {
    perfersColorSchemeUpdate () {
      this.perfersColorSchemeMedia = window.matchMedia('(perfers-color-scheme: dark)')
      this.color = this.perfersColorSchemeMedia.matches ? 'dark': 'light'
    }
  }
}
代码语言:txt
AI代码解释
复制
import perfersColorSchemeMixin from './perfersColorSchemeMixin.js'
import aspectRatioMixin from './aspectRatioMixin.js'
export default {
  name: 'SystemColor',
  mixins: [perfersColorSchemeMixin, aspectRatioMixin],
  data () {
    return {
      color: '',
      is16than9: false
    }
  },
  created () {
    this.perfersColorSchemeUpdate()
    this.perfersColorSchemeMedia.addEventListener('change', this.perfersColorSchemeUpdate)

    this.aspectRatioUpdate()
    this.aspectRatioMedia.addEventListener('change', this.aspectRatioUpdate)
  },
  destroyed () {
    this.perfersColorSchemeMedia.removeEventListener('change', this.perfersColorSchemeUpdate)
    this.aspectRatioMedia.removeEventListener('change', this.aspectRatioUpdate)
  } 
}

当然我们也可以把 data 以及 created 中的内容也抽离到 mixins 中。但这样会导致模板中使用的变量不知道来自哪个 mixins,且可能存在命名冲突等问题。此时如果我们想再增加第3个新增功能,需要各个地方增加,阅读性变差、难以维护。

正是这种碎片化使得理解和维护一个复杂的组件变得非常困难。选项的强行分离为展示背后的逻辑关注点设置了障碍。此外,在处理单个逻辑关注点时,我们必须不断地在选项代码块之间“跳转”,以找到与该关注点相关的部分。

vue3 composition api

当我们在组件间提取并复用逻辑时,组合式(@vue/runtime-core) API 是十分灵活的。一个组合函数仅依赖它的参数和 Vue 全局导出的 API,而不是依赖其微妙的 this 上下文。你可以将组件内的任何一段逻辑导出为函数以复用它。

  • 基于响应式
  • 提供 vue 的生命周期钩子
  • 组件销毁时自动销毁依赖监听
  • 可复用的逻辑

组件可以变得如此清爽

代码语言:txt
AI代码解释
复制
import { reactive, toRefs } from 'vue'
import usePrefersColorScheme from './usePrefersColorScheme.js'
import useAspectRatio from './useAspectRatio.js'
export default {
  name: 'SystemColor',
  setup () {
    let color = usePrefersColorScheme()	// ① 仅此一处
    let is16than9 = useAspectRatio()		// ② 仅此一处
    return {
      color,
      is16than9
    }
  }
}

下述可组合式函数,建议使用 use 作为函数名的开头,以表示它是一个组合函数

代码语言:txt
AI代码解释
复制
/* ① usePrefersColorScheme.js */
import { ref, onUnmounted, onMounted } from 'vue'
export default function usePrefersColorScheme () {
  let media 
  let color = ref(null)

  const update = () => {
    media = window.matchMedia('(perfers-color-scheme: dark)')
    color.value = media.matches ? 'dark': 'light'
  }
  
  update()
  media.addEventListener('change', update)
  onUnmounted(() => {
    media.removeEventListener('change', update)
  })

  return color
}
代码语言:txt
AI代码解释
复制
/* ② useAspectRatio.js */
import { ref, onUnmounted, onMounted } from 'vue'
export default function usePrefersColorScheme () {
  let media
  let is16than9 = ref(null)

  const update = () => {
    media = window.matchMedia('(aspect-ratio: 16/9)')
    is16than9.value = media.matches
  }
  
  update()
  media.addEventListener('change', update)
  onUnmounted(() => {
    media.removeEventListener('change', update)
  })

  return is16than9
}

这些组合函数里面他都可以使用生命周期的钩子,可以自动更新和自动注销。在使用的时候也就没有了负担,只需要去留意每一个 ref 对应什么样的功能,其更好的提高代码的复用度、可读性、可维护性。

相比而言,组合式 API:

  • 暴露给模板的 property 来源十分清晰,因为它们都是被组合逻辑函数返回的值
  • 不存在命名空间冲突,可以通过解构任意命名
  • 不再需要仅为逻辑复用而创建的组件实例

其他

Vue 3 已经可以使用的有两个主要的逻辑的组件库,vueusevue-composable

  • vueuse:提供了更加细粒度的 Web API 以及工具分装
  • vue-composable:提供了更多常用的逻辑封装。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
vue3 -- 通过简单示例,聊一聊Composition API
在 vue3 版本之前,我们复用组件(或者提取和重用多个组件之间的逻辑),通常有以下几种方式:
奋飛
2021/08/30
5290
vue3 -- 通过简单示例,聊一聊Composition API
打包 Composition API、Vue3
到目前为止 Vue 为我们提供了两种开发组件的 API 风格,选项式 API 和组合式 API。组合式 API 可以由我们导入不同的 API 函数来描述组件的逻辑,在 SFC 组件中通常还会在 script 标签显示标注setup来使用。
前端小鑫同学
2022/12/26
6100
VueJs中如何自定义hooks(组合式)函数
在Vue当中,一个非常重要的功能就是组件的复用,编写Vue组件,更多的也是在拼装组件,将页面的各个功能进行模块化
itclanCoder
2023/02/26
6980
VueJs中如何自定义hooks(组合式)函数
Vue3.0 所采用的 Composition Api 与 Vue2.x 使用的 Options Api 有什么不同?
Composition API 可以说是Vue3最大的特点,那么为什么要推出Composition Api,解决了什么问题?
@超人
2021/03/18
1K0
Vue3.0 所采用的 Composition Api 与 Vue2.x 使用的 Options Api 有什么不同?
一张动图理解Vue3的Composition Api
这个文章其实很简单, 只要能说明composition的好处,就是极好的,我们用一个非常简单的万金油场景,比如我们有一个非常简单的to do list
用户8983410
2021/09/19
5070
做了一夜动画,就为让大家更好的理解Vue3的Composition Api
这个文章其实很简单, 只要能说明composition的好处,就是极好的,我们用一个非常简单的万金油场景,比如我们有一个非常简单的to do list
前端达人
2021/01/27
3520
做了一夜动画,就为让大家更好的理解Vue3的Composition Api
vue3的Composition API
Composition API 也叫组合式API, 是在vue3中新引入的一种API,vue2中已经有option API了,那为什么要新稿这么一套呢,其实主要原因是要解决vue2中的option API的在处理复杂组件逻辑的局限性,例如逻辑分散、代码复用性差、类型推断困难、组件组织混乱、响应式系统限制、模板逻辑复杂性、组件测试困难等问题。为此Composition API通过函数的方式来组织代码,使得逻辑更加模块化和可组合,这就变得很灵活。
iwhao
2024/08/04
1190
vue3的composition-api实践总结
因为向往已久vue3的开发方式,但是组内有很多历史项目,并且我们受制于ie的支持,所以我们决定在vue2中引入composition-api,来使用他的新特性。在使用过程中,我们遇到了很多问题,也积累了一些经验,所以记录下。
winty
2021/07/27
8860
vue 随记(3):“新时代”的姿势
•性能上:最多比vue2 快2倍•静态标记提升•proxy取代defineProperty•tree shaking:按需编译打包代码•composition api :类似hook的编码风格•支持typescript:面向未来目前的代码 98% 以上使用 TypeScript 编写。如果你还没有学习 TypeScript,请尽快学习,否则可能看不懂源码。另外有件事情说出来可能会让你非常惊讶,Vue 3 的源代码完全没有使用 class 关键字!(只在测试代码和示例代码里用到了 class 关键字)•custom renderer api:自定义渲染
一粒小麦
2020/07/21
6810
Vue3学习笔记(二)——组合式API(Composition API)
官方文档: https://v3.cn.vuejs.org/guide/composition-api-introduction.html
张果
2022/10/31
4.4K0
Vue3学习笔记(二)——组合式API(Composition API)
【译】Vue 3 Composition API: Ref vs Reactive
Vue 3.0发布至今已经大半年过去了,我从最初的Option API的思维转换成Composition API花了很长时间,在使用过程中也出现了很多问题。我们都知道Ref和Reactive都是定义响应式数据的方式,而我在初学的时候从网上的大部分博客只得出过一个结论:Ref是定义基本类型数据,Reactive是定义引用类型数据的,但随着后面的实践发现,其实并不是很严谨,于是我找了这么一篇文章,我觉得讲得很好,便有了今天的翻译。下面的原文翻译采用意译并非直译,如有错误,请诸君批评与指正。
前端达人
2021/05/11
2K0
vue3 day4
vue3中依然可以使用v2的配置方式来定义生命周期钩子,但是有两个生命周期更改了名字
花花522
2023/03/07
2730
vue3 day4
再遇vue之vue3新特性
首先说明一下,vue2和vue3是Vue.js的两个主要版本。目前vue3已经更新到3.3.4的版本了
用户6297767
2023/11/21
5390
再遇vue之vue3新特性
Composition API详解
setup()函数是vue3中专门新增的方法,可以理解为Composition Api的入口。
前端老道
2022/12/01
1.4K0
面试官:Vue3.0的设计目标是什么?做了哪些优化?
不以解决实际业务痛点的更新都是耍流氓,下面我们来列举一下Vue3之前我们或许会面临的问题
@超人
2021/02/26
4580
面试官:Vue3.0的设计目标是什么?做了哪些优化?
Vue3 初探
3.更友好 提出 composition Api,无论代码的编写还是查看都更加清晰方便
epoos
2022/06/06
7800
学习 Vue 3 全家桶 - Vite 和 Composition API
如果在一个页面里有多个功能,那就需要在 data 和 methods 里分别进行配置。但这样的话,数据和方法相关的代码会写在一起,在组件代码行数多了后就不好维护。可以使用 Composition API 的逻辑来拆分代码,把一个功能相关的数据和方法都维护在一起。
Cellinlab
2023/05/17
4240
学习 Vue 3 全家桶 - Vite 和 Composition API
Vue3 关于组合式API
组合式 API (Composition API) 是一系列 API 的集合,使我们可以使用函数而不是声明选项的方式书写 Vue 组件。
程序员海军
2023/11/05
2070
Vue3 对比Vue2,你找到哪些变化?
希望本篇文章能帮你加深对 Vue 的理解,能信誓旦旦地说自己熟练Vue2/3。除此之外,也希望路过的朋友可以帮助我查漏补缺🤞。 内容混杂用法 + 原理 + 使用小心得,建议收藏,慢慢看。 区别 生命周期的变化 整体来看,变化不大,只是名字大部分需要 + on,功能上类似。使用上 Vue3 组合式 API 需要先引入;Vue2 选项 API 则可直接调用,如下所示。 // vue3 <script setup> import { onMounted } from 'vue' onMounted(
@超人
2022/04/14
1.1K0
vue3知识点:自定义hook函数
答案:请看官方文档: https://v3.cn.vuejs.org/guide/composition-api-introduction.html
刘大猫
2024/10/31
1340
相关推荐
vue3 -- 通过简单示例,聊一聊Composition API
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档