Composition组合API在setup函数中的使用

11388次阅读 554人点赞 作者: WuBin 发布时间: 2021-07-14 11:22:47
扫码到手机查看

为什么需要Vue对组合API

目前在Vue世界中,最热门的话题是Composition API,这是Vue 3.0中引入的基于函数的API。 在本文中,我们将学习这个新API的需求,然后学习如何使用基于函数的API。

在我们深入探讨之前,无需担心组合API将彻底改变Vue。 Composition API是现有组件附加的功能,因此Vue 3.0中没有重大更改此外,Vue团队还创建了一个与Vue 2.x兼容的插件(vue-composition)。

随着Vue的日益普及,人们也开始在大型和企业级应用程序中采用Vue。 由于这种情况,在很多情况下,此类应用程序的组件会随着时间的推移而逐渐增长,并且有时使用单文件组件人们很难阅读和维护。 因此,需要以逻辑方式制动组件,而使用Vue的现有API则不可能。

代替添加另一个新概念,提议使用Composition API,该API基本将Vue的核心功能(如创建响应式数据)公开为独立功能,并且该API有助于在多个组件之间编写简洁且可复用的代码。

组合API在vue组件中的应用

比如有一个组件,使用了组合API,文件结构如下:

注意文件命名规则,使用组合API时,在组件目录下的JS文件命名为use-xxxx.js

通过ref拿到DOM元素

具体请参见:Vue3-setup在渲染函数中通过ref访问Dom元素

向逻辑中传入props

<index-list :data="singers"></index-list>
// 在index-list.vue中
import useFixed from './use-fixed'
props: {
    data: {
      type: Array,
      default () {
        return []
      }
    }
},
setup(props) {
   const { ... } = useFixed(props);
   return {....]
}

在use-fixed.js中使用props中data的数据:

export default function useFixed (props) {
   const group = props.data[...]
}

在逻辑中使用computed、watch和nextTick,并与模板中映射

注意在组合API中,许多属性都需要手动的进行引入。

在index-list.vue中:

<div class="fixed" v-show="fixedTitle">...</div>
import useFixed from './use-fixed'
setup(props) {
  // 因为可能返回多个属性或方法,这里使用解构赋值
   const { fixedTitle } = useFixed(props)
   // 要想让属性在模板中生效,必须要在setup中返回!
   return {
      fixedTitle
    }
}

在use-fixed.js中:

import { ref, watch, computed, nextTick } from 'vue'
export default function useFixed (props) {
    // 使用ref创建响应式的数据
    const scrollY = ref(0)

    // 计算属性注意也需要引入
    const fixedTitle = computed(() => {
        return '...'
    })

    // 使用watchAPI也需要引入,vue3的watch要监听一个getter函数
    // () => props.data就是监听的数据,后面就是监听到变化后执行的函数
    watch(() => props.data, async () => {
        // 因为监听到数据的变化后,DOM不一定会立即发生变化
        // 这是一个异步过程 所以等nextTick DOM更新完后再进行计算
        await nextTick()
        // do...
    })

    // 监听某个值的变化 也可以用getter函数
    watch(scrollY, (newY) => {
        // do...
    })

    return {
        fixedTitle
    }
}

获取ref对象真正的值

import { ref } from 'vue'

// 初始化ref对象
const groupRef = ref(null)

// ref对象为一个整数
const scrollY= ref(0)
// 要获取ref对象中的值 记得使用ref_obj.value
if (scrollY.value < 0) { return '' }

模板中应用逻辑文件中的方法

在index-list.vue中:

<div  @touchstart.stop.prevent="onShortcutTouchStart">...</div>

import useShortcut from './use-shortcut'
setup(props) {
   const { groupRef } = useFixed(props)
   // 还可以将其他逻辑文件中返回的对象,当作参数传入其他逻辑处理中
   const { onShortcutTouchStart } = useShortcut(props, groupRef)
   
   // 必须在setup中返回才能生效
   return {
      groupRef,
      onShortcutTouchStart,
   }
}

在use-shortcut.js中:

export default function useShortcut(props, groupRef) {
   function onShortcutTouchStart (e) {
      // do...
   }
   // 模板中要用到的属性与方法一定要返回出去!
   return {
    onShortcutTouchStart
   }
}

获取其他组件、注册事件和使用钩子函数

在scroll.vue中:

<div ref="rootRef">
    <!-- 内容插槽 -->
    <slot></slot>
</div>

// 注册向外派发的事件
emits: ['scroll'],
props: {
    click: {
      type: Boolean,
      default: true
    },
    // 决定是否可以监听到向外派发的滚动事件 3就是只要滚动就派发
    probeType: {
      type: Number,
      default: 0
    }
},
setup(props, { emit }) {
    const rootRef = ref(null)
    // 接收到返回的scroll实例,并将返回的实例再暴漏(return)出去
    // 之后就可以通过scroll组件的实例,就可以访问到这个scroll变量了
    // 并通过这个变量拿到BS的实例了 通过在组件上添加ref拿到组件实例
    const scroll = useScroll(rootRef, props, emit)

    // 一定要return一个对象包含这个ref才会有效
    return {
      rootRef,
      scroll
    }
}

在use-scroll.js中:

import BScroll from '@better-scroll/core/'
import { onMounted, onUnmounted, ref } from 'vue'

export default function useScroll(wrapperRef, options, emit) {
    // 闭包中注册一个局部变量
    const scroll = ref(null)

  onMounted(() => {
    // scroll也是一个ref对象,所以他的值要存在value上,才会被数据响应
    scroll.value = new BScroll(wrapperRef.value, {
      ...options
    })

    scroll.value.on('scroll', (pos) => {
       // 向外派发scroll事件 让引用的组件接收
       emit('scroll', pos)
    })
  })

  // 对scroll实例卸载逻辑
  onUnmounted(() => {
    scroll.value.destroy()
  })

  // 将scroll实例暴漏出去
  return scroll
}

在index-list.vue中:

<scroll
  @scroll="组件派发的scroll滚动事件"
  ref="scrollRef"
>
...
</scroll>

import Scroll from '@/components/base/scroll/scroll'
import useShortcut from './use-shortcut'

setup(props) {
    const { scrollRef } = useShortcut(props)
    // 一定要记得在setup中返回
    return {
       scrollRef
    }
}

在use-shortcut.js中:

import { ref } from 'vue'

export default function useShortcut(props, groupRef) {
   const scrollRef = ref(null)
   // scrollRef.value对应的就是scroll组件的实例
   // .scroll就是返回的scroll对象 具体操作的话 请console.log打印后查看对象
   const scroll = scrollRef.value.scroll
   // 这个是better-scroll自带的滚动到元素的方法
   scroll.scrollToElement('某个元素', 0)

   // 因为可能会返回更多东西,所以使用对象方式
   return {
    scrollRef
  }
}

定义一个ref属性,修改或者使用其值

在setup钩子中,如果定义了一个ref,并想通过它进行判断,必须使用.value。

<audio @canplay="ready"
       :data-ok="songReady ? '1' : '2'"
></audio>

setup() {
    // 定义一个ref并赋予初始值false
    const songReady = ref(false)

    function ready() {
      // 在js中取值必须使用.value,但是在模板中的话就不需要了
      if (songReady.value) {
        return
      }
      // 因为定义了一个ref所以如果要修改它的值必须使用.value
      songReady.value = true
    }

    return {
       // 模板中要使用 必须return
        songReady,
        ready
    }
}

点赞 支持一下 觉得不错?客官您就稍微鼓励一下吧!
关键词:Vue3,Composition-API
推荐阅读
  • uniapp实现被浏览器唤起的功能

    当用户打开h5链接时候,点击打开app若用户在已经安装过app的情况下直接打开app,若未安装过跳到应用市场下载安装这个功能在实现上主要分为两种场景,从普通浏览器唤醒以及从微信唤醒。

    9265次阅读 597人点赞 发布时间: 2022-12-14 16:34:53 立即查看
  • Vue

    盘点Vue2和Vue3的10种组件通信方式

    Vue中组件通信方式有很多,其中Vue2和Vue3实现起来也会有很多差异;本文将通过选项式API组合式API以及setup三种不同实现方式全面介绍Vue2和Vue3的组件通信方式。

    4003次阅读 297人点赞 发布时间: 2022-08-19 09:40:16 立即查看
  • JS

    几个高级前端常用的API

    推荐4个前端开发中常用的高端API,分别是MutationObserver、IntersectionObserver、getComputedstyle、getBoundingClientRect、requ...

    14243次阅读 930人点赞 发布时间: 2021-11-11 09:39:54 立即查看
  • PHP

    【正则】一些常用的正则表达式总结

    在日常开发中,正则表达式是非常有用的,正则表达式在每个语言中都是可以使用的,他就跟JSON一样,是通用的。了解一些常用的正则表达式,能大大提高你的工作效率。

    13090次阅读 455人点赞 发布时间: 2021-10-09 15:58:58 立即查看
  • 【中文】免费可商用字体下载与考证

    65款免费、可商用、无任何限制中文字体打包下载,这些字体都是经过长期验证,经得住市场考验的,让您规避被无良厂商起诉的风险。

    11732次阅读 939人点赞 发布时间: 2021-07-05 15:28:45 立即查看
  • Vue

    Vue3开发一个v-loading的自定义指令

    在vue3中实现一个自定义的指令,有助于我们简化开发,简化复用,通过一个指令的调用即可实现一些可高度复用的交互。

    15843次阅读 1263人点赞 发布时间: 2021-07-02 15:58:35 立即查看
  • JS

    关于手机上滚动穿透问题的解决

    当页面出现浮层的时候,滑动浮层的内容,正常情况下预期应该是浮层下边的内容不会滚动;然而事实并非如此。在PC上使用css即可解决,但是在手机端,情况就变的比较复杂,就需要禁止触摸事件才可以。

    14926次阅读 1216人点赞 发布时间: 2021-05-31 09:25:50 立即查看
  • Vue

    Vue+html2canvas截图空白的问题

    在使用vue做信网单页专题时,有海报生成的功能,这里推荐2个插件:一个是html2canvas,构造好DOM然后转canvas进行截图;另外使用vue-canvas-poster(这个截止到2021年3月...

    29262次阅读 2299人点赞 发布时间: 2021-03-02 09:04:51 立即查看
  • Vue

    vue-router4过度动画无效解决方案

    在初次使用vue3+vue-router4时候,先后遇到了过度动画transition进入和退出分别无效的情况,搜遍百度没没找到合适解决方法,包括vue-route4有一些API都进行了变化,以前的一些操...

    25285次阅读 1948人点赞 发布时间: 2021-02-23 13:37:20 立即查看
交流 收藏 目录