Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >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
vue3知识点:自定义hook函数
答案:请看官方文档: https://v3.cn.vuejs.org/guide/composition-api-introduction.html
刘大猫
2024/10/31
1350
一张动图理解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和vue2的API风格对比
Vue3 组合式 API(Composition API) 主要用于在大型组件中提高代码逻辑的可复用性。
言程序
2024/07/02
2510
打包 Composition API、Vue3
到目前为止 Vue 为我们提供了两种开发组件的 API 风格,选项式 API 和组合式 API。组合式 API 可以由我们导入不同的 API 函数来描述组件的逻辑,在 SFC 组件中通常还会在 script 标签显示标注setup来使用。
前端小鑫同学
2022/12/26
6100
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 有什么不同?
VueJs中如何自定义hooks(组合式)函数
在Vue当中,一个非常重要的功能就是组件的复用,编写Vue组件,更多的也是在拼装组件,将页面的各个功能进行模块化
itclanCoder
2023/02/26
7000
VueJs中如何自定义hooks(组合式)函数
再遇vue之vue3新特性
首先说明一下,vue2和vue3是Vue.js的两个主要版本。目前vue3已经更新到3.3.4的版本了
用户6297767
2023/11/21
5390
再遇vue之vue3新特性
面试官:Vue3.0的设计目标是什么?做了哪些优化?
不以解决实际业务痛点的更新都是耍流氓,下面我们来列举一下Vue3之前我们或许会面临的问题
@超人
2021/02/26
4590
面试官:Vue3.0的设计目标是什么?做了哪些优化?
vue3 day4
vue3中依然可以使用v2的配置方式来定义生命周期钩子,但是有两个生命周期更改了名字
花花522
2023/03/07
2740
vue3 day4
vue3.0 Composition API 上手初体验 函数组件的开发与使用
在上一节中,我们讨论了普通组件的开发与使用,其实相比较 vue 2.0 来说,差别并不大。
FungLeo
2020/05/26
1.3K0
Vue3 对比Vue2,你找到哪些变化?
希望本篇文章能帮你加深对 Vue 的理解,能信誓旦旦地说自己熟练Vue2/3。除此之外,也希望路过的朋友可以帮助我查漏补缺🤞。 内容混杂用法 + 原理 + 使用小心得,建议收藏,慢慢看。 区别 生命周期的变化 整体来看,变化不大,只是名字大部分需要 + on,功能上类似。使用上 Vue3 组合式 API 需要先引入;Vue2 选项 API 则可直接调用,如下所示。 // vue3 <script setup> import { onMounted } from 'vue' onMounted(
@超人
2022/04/14
1.1K0
vue3的Composition API
Composition API 也叫组合式API, 是在vue3中新引入的一种API,vue2中已经有option API了,那为什么要新稿这么一套呢,其实主要原因是要解决vue2中的option API的在处理复杂组件逻辑的局限性,例如逻辑分散、代码复用性差、类型推断困难、组件组织混乱、响应式系统限制、模板逻辑复杂性、组件测试困难等问题。为此Composition API通过函数的方式来组织代码,使得逻辑更加模块化和可组合,这就变得很灵活。
iwhao
2024/08/04
1220
整理的一些 Vue3 知识点
看完你就基本可以上手搞开发了,本文适合Vue初学者,或者Vue2迁移者,当然还是建议Vue3官网完全过一遍。不适合精通原理,源码的大佬们。
coder_koala
2021/10/12
2.6K0
整理的一些 Vue3 知识点
vue3中可以帮助你早点下班的9个开发技巧!
vue3也发布很长时候了,官方也将默认版本切换为vue3,而且也出现了完善的中文文档,不知同志们是否已经使用了了呢?
用户7413032
2022/04/01
1.1K0
vue3中可以帮助你早点下班的9个开发技巧!
vue-demi
然后修改package.json,将vue 和@vue/composition-api添加到peerDependencies中
阿超
2023/08/17
3770
当Vue2遇到Composition API,它们之前到底能擦出怎样的火花?
Composition API是什么?也称为组合式 API。如果你第一次听到这个词,请认真读完这篇文章。
Vam的金豆之路
2021/12/01
1.3K0
学习 Vue 3 全家桶 - Vite 和 Composition API
如果在一个页面里有多个功能,那就需要在 data 和 methods 里分别进行配置。但这样的话,数据和方法相关的代码会写在一起,在组件代码行数多了后就不好维护。可以使用 Composition API 的逻辑来拆分代码,把一个功能相关的数据和方法都维护在一起。
Cellinlab
2023/05/17
4250
学习 Vue 3 全家桶 - Vite 和 Composition API
Vue3 关于组合式API
组合式 API (Composition API) 是一系列 API 的集合,使我们可以使用函数而不是声明选项的方式书写 Vue 组件。
程序员海军
2023/11/05
2070
相关推荐
vue3 -- 通过简单示例,聊一聊Composition API
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档