百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分类 > 正文

VueUse中的这5个函数,也太好用了吧

ztj100 2024-12-03 06:52 22 浏览 0 评论

本已经原作者授权翻译

VueUse 是 Anthony Fu 大佬的一个开源项目,它为Vue的开发者提供了大量用于 Vue2 和Vue3 的基本 Composition API 实用工具函数。

它有几十个用于常见开发人员用例的解决方案,如跟踪ref更改,检测元素可见性,简化常见Vue模式,键盘/鼠标输入等。 这是真正节省开发时间的好方法,因为我们不必自己亲手添加所有这些标准功能,拿来主义,用就对了(再次感谢大佬的付出)。

我喜欢VueUse库,因为它在决定提供哪些实用工具时真正把开发者放在第一位,而且它是一个维护良好的库,因为它与Vue的当前版本保持同步。

VueUse 有哪些实用方法?

如果你想看到每一个实用程序的完整列表,建议去看看官方文档。但总结一下,VueUse 中有9种类型的函数。

  • Animation(动画) - 包含易于使用的过渡、超时和计时功能
  • Browser (浏览器) - 可以用于不同的屏幕控件、剪贴板、首选项等等
  • Component (组件) - 为不同的组件方法提供简写
  • Sensors (传感器)- 用来监听不同的DOM事件、输入事件和网络事件
  • State (状态) - 管理用户状态(全局,本地存储,会话存储)
  • Utility (实用方法)--不同的实用方法,如gettersconditionalsref synchronization等。
  • Watch --更高级的观察器类型,如可暂停的观察器、放弃的观察器和条件观察器
  • 其它 - 事件、WebSockets和 Web workers 的不同类型的功能

将 Vueuse 安装到 Vue 项目中

VueUse 的最大特点之一是,它只用一个包就能兼容 Vue2 和 Vue3!

安装VueUse有两种选择:npmCDN

npm i @vueuse/core # yarn add @vueuse/core
<script src="https://unpkg.com/@vueuse/shared"></script>
<script src="https://unpkg.com/@vueuse/core"></script>

推荐使用NPM,因为它更容易理解,但如果我们使用CDN, 可能通过 window.VueUse 来访问。

使用 npm,可以通过解构的方式来获得想要的方法:

import { useRefHistory } from '@vueuse/core'

useRefHistory 跟踪响应式数据的变化

useRefHistory跟踪对 ref 所做的每一个改变,并将其存储在一个数组中。这样我们能够轻松为应用程序提供撤销做功能。

来看一个示例,在该示例中,我们做一个能够撤销的文本区域

第一步是在没有 VueUse 的情况下创建我们的基本组件--使用reftextarea、以及用于撤销和重做的按钮。

<template>
  <p> 
    <button> Undo </button>
    <button> Redo </button>
  </p>
  <textarea v-model="text"/>
</template>

<script setup>
import { ref } from 'vue'
const text = ref('')
</script>

<style scoped>
  button {
    border: none;
    outline: none;
    margin-right: 10px;
    background-color: #2ecc71;
    color: white;
    padding: 5px 10px;;
  }
</style>

接着,导入useRefHistory,然后通过 useRefHistorytext 中提取historyundoredo属性。

import { ref } from 'vue'
import { useRefHistory } from '@vueuse/core'

const text = ref('')
const { history, undo, redo } = useRefHistory(text)

每当我们的ref发生变化,更新history属性时,就会触发一个监听器。

为了看看底层做了什么,我们把 history 内容打印出来。并在单击相应按钮时调用 undoredo函数。

<template>
  <p> 
    <button @click="undo"> Undo </button>
    <button @click="redo"> Redo </button>
  </p>
  <textarea v-model="text"/>
  <ul>
    <li v-for="entry in history" :key="entry.timestamp">
      {{ entry }}
    </li>
  </ul>
</template>

<script setup>
import { ref } from 'vue'
import { useRefHistory } from '@vueuse/core'
const text = ref('')
const { history, undo, redo } = useRefHistory(text)
</script>

<style scoped>
  button {
    border: none;
    outline: none;
    margin-right: 10px;
    background-color: #2ecc71;
    color: white;
    padding: 5px 10px;;
  }
</style>

直接,跑起来,效果如下:

还有不同的选项,为这个功能增加更多的功能。例如,我们可以深入追踪 reactive 对象,并像这样限制 history 记录的数量。

const { history, undo, redo } = useRefHistory(text, {
  deep: true,
  capacity: 10,
})

onClickOutside 关闭 modal

onClickOutside 检测在一个元素之外的任何点击。根据我的经验,这个功能最常见的使用情况是关闭任何模态或弹出窗口。

通常,我们希望我们的模态屏蔽网页的其余部分,以吸引用户的注意和限制错误。然而,如果他们确实点击了模态之外,我们希望它关闭。

要做到这一点,只有两个步骤。

  • 为要检测的元素创建一个模板引用
  • 使用这个模板ref运行onClickOutside

这是一个简单的组件,使用onClickOutside弹出窗口。

<template>
  <button @click="open = true"> Open Popup </button>
  <div class="popup" v-if='open'>
    <div class="popup-content" ref="popup">
      Lorem ipsum dolor sit amet consectetur adipisicing elit. Corporis aliquid autem reiciendis eius accusamus sequi, ipsam corrupti vel laboriosam necessitatibus sit natus vero sint ullam! Omnis commodi eos accusantium illum?
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { onClickOutside } from '@vueuse/core'
const open = ref(false) // state of our popup
const popup = ref() // template ref
// whenever our popup exists, and we click anything BUT it
onClickOutside(popup, () => {
  open.value  = false
})
</script>

<style scoped>
  button {
    border: none;
    outline: none;
    margin-right: 10px;
    background-color: #2ecc71;
    color: white;
    padding: 5px 10px;;
  }
  .popup {
    position: fixed;
    top: ;
    left: ;
    width: 100vw;
    height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(, , , 0.1);
  }
  .popup-content {
    min-width: 300px;
    padding: 20px;
    width: 30%;
    background: #fff;
  }
</style

结果是这样的,我们可以用我们的按钮打开弹出窗口,然后在弹出内容窗口外单击关闭它。


useVModel 简化 v-model 的绑定。

Vue开发者的一个常见用例是为一个组件创建一个自定义的v-model绑定。这也要求我们的组件接受一个 value 作为 prop,每当这个 value 被修改,我们的组件就会向父类发出一个 update 事件。

useVModel函数将其简化为只使用标准的ref语法。假设我们有一个自定义的文本输入,试图为其文本输入的值创建一个v-model通常情况下,我们必须接受一个 value的 prop,然后发出一个 change事件来更新父组件中的数据值。

我们可以使用useVModel,把它当作一个普通的ref,而不是使用ref并调用props.valueupdate:value这有助于减少我们需要记住的不同语法的数量!

<template>
    <div>
        <input 
            type="text" 
            :value="data"
            @input="update"
        />
    </div>
</template>

<script>
import { useVModel } from '@vueuse/core'
export default {
  props: ['data'],
  setup(props, { emit }) {
    const data = useVModel(props, 'data', emit)
    console.log(data.value) // equal to props.data
    data.value = 'name' // equal to emit('update:data', 'name')
    const update = (event) => {
        data.value = event.target.value
    }
    return {
        data,
        update
    }
  },
}
</script>

每当需要访问value时,我们只需调用.valueuseVModel将从我们的组件 props 中给我们提供值。而每当改变对象的值时,useVModel 会向父组件发出一个更新事件。

下面是父组件的一个简单示例

<template>
  <div>
    <p> {{ data }} </p>
    <custom-input 
      :data="data" 
      @update:data="data = $event"
    />
  </div>
</template>

<script>
import CustomInput from './components/CustomInput.vue'
import { ref } from 'vue'
export default {
  components: {
    CustomInput,
  },
  setup () {
    const data = ref('hello')
    return {
      data
    }
  }
}

运行结果如下,父方的值总是与子方的输入保持同步:


使用 intersectionobserver 跟踪元素的可见性

当确定两个元素是否重叠时,useIntersectionObserver 是非常强大的。这方面的一个很好的用例是检查一个元素在视口中是否当前可见。

基本上,它检查目标元素与根元素/文档相交的百分比。如果这个百分比超过了某个阈值,它就会调用一个回调,确定目标元素是否可见。

useIntersectionObserver提供了一个简单的语法来使用IntersectionObserver API。我们所需要做的就是为我们想要检查的元素提供一个模板ref

默认情况下,IntersectionObserver将以文档的视口为根基,阈值为0.1--所以当这个阈值在任何一个方向被越过时,我们的交集观察器将被触发。

示例:我们有一个假的段落,只是在我们的视口中占据了空间,目标元素,然后是一个打印语句,打印我们元素的可见性。


<template>
  <p> Is target visible? {{ targetIsVisible }} </p>
  <div class="container">
    <div class="target" ref="target">
      <h1>Hello world</h1>
    </div>
  </div>
</template>

<script>
import { ref } from 'vue'
import { useIntersectionObserver } from '@vueuse/core'
export default {
  setup() {
    const target = ref(null)
    const targetIsVisible = ref(false)
    const { stop } = useIntersectionObserver(
      target,
      ([{ isIntersecting }], observerElement) => {
        targetIsVisible.value = isIntersecting
      },
    )
    return {
      target,
      targetIsVisible,
    }
  },
}
</script>

<style scoped>
.container {
  width: 80%;
  margin:  auto;
  background-color: #fafafa;
  max-height: 300px;
  overflow: scroll;
}
.target {
  margin-top: 500px;
  background-color: #1abc9c;
  color: white;
  padding: 20px;
}
</style>

运行后,对应的值会更新:

我们还可以为我们的 Intersection Observer 指定更多的选项,比如改变它的根元素、边距(计算交叉点时对根的边界框的偏移)和阈值水平。

const { stop } = useIntersectionObserver(
      target,
      ([{ isIntersecting }], observerElement) => {
        targetIsVisible.value = isIntersecting
      },
      {
        // root, rootMargin, threshold, window
        // full options in the source: https://github.com/vueuse/vueuse/blob/main/packages/core/useIntersectionObserver/index.ts
        threshold: 0.5,
      }
)

同样重要的是,这个方法返回一个 stop 函数,我们可以调用这个函数来停止观察交叉点。如果我们只想追踪一个元素在屏幕上第一次可见的时候,这就特别有用。

在这段代码中,一旦targetIsVisible被设置为true,observer 就会停止,即使我们滚动离开目标元素,我们的值也会保持为 true

const { stop } = useIntersectionObserver(
      target,
      ([{ isIntersecting }], observerElement) => {
        targetIsVisible.value = isIntersecting
        if (isIntersecting) {
          stop()
        }
      },
    )

使用 useTransition 做个数字加载动画

useTransition是整个VueUse库中我最喜欢的函数之一。它允许我们只用一行就能顺利地在数值之间进行过渡。

如果使用 useTransition 做一个下面这样的效果,要怎么做呢?

我们可以通过三个步骤来做到这一点。

  • 初始化一个 ref 变量 count ,初始值为 0
  • 使用 useTransition 创建一个变量 output
  • 改变 count 的值
import { ref } from 'vue'
import { useTransition, TransitionPresets } from '@vueuse/core'

const count = ref(0)

const output = useTransition(count , {
  duration: 3000,
  transition: TransitionPresets.easeOutExpo,
})

count.value = 5000

</script>

然后在 template 中显示 output 的值:

<template>
  <h2> 
    <p> Join over </p>
    <p> {{ Math.round(output) }}+ </p>
    <p>Developers </p>
  </h2>
</template>

<script setup>
import { ref } from 'vue'
import { useTransition, TransitionPresets } from '@vueuse/core'
const count = ref(0)
const output = useTransition(count, {
  duration: 3000,
  transition: TransitionPresets.easeOutExpo,
})
count.value = 5000
</script>

运行结果:

我们还可以使用useTransition 转换整个数字数组。 使用位置或颜色时,这非常有用。 使用颜色的一个很好的技巧是使用计算的属性将RGB值格式化为正确的颜色语法。

<template>
  <h2 :style="{ color: color } "> COLOR CHANGING </h2>
</template>

<script setup>
import { ref, computed } from 'vue'
import { useTransition, TransitionPresets } from '@vueuse/core'
const source = ref([, , ])
const output = useTransition(source, {
  duration: 3000,
  transition: TransitionPresets.easeOutExpo,
})
const color = computed(() => {
  const [r, g, b] = output.value
  return `rgb(${r}, ${g}, ${b})`
})
source.value = [255, , 255]
</script>

总结

这不是VueUse的完整指南。这些只是我平常比较常用的函数,还有很多好用的函数,大家可以自行到官网去学习使用。

~完,我去刷碗了,周末不刷碗,晚上跪榴莲。

作者:Matt Maribojoc 译者:前端小智 来源:medium 原文:https://learvue.co/2021/07/5-vueuse-library-functions-that-can-speed-up-development/

相关推荐

xls文件保存宏_excel如何保存宏为其他文件使用

一、直接保存为旧版.xls格式(兼容性优先)1.操作方法-在Excel中打开文件→点击「文件」→「另存为」→保存类型选择“Excel97-2003工作簿(*.xls)”。-系统...

C 插入或删除word分页符_怎么删除插了分页符的空白页

分页符是word中常用的一种分页的符号,它标志着上一页的结束和下一页的开始。在word中分页符有两种,一种是自动分页符,也叫软分页符,即一页数据写满以后转到下一页时word自动插入的一个分页符;另一种...

177.C# SqlSugar 删除数据_sql删除数据代码

摘要普通删除、单表删除、表达式删除,子查询删除正文根据主键Where条件删除varret=Db.Deleteable<wms_user>().Where(newwms_user...

C#使用handle实现获取占用指定文件或文件夹的进程(Locksmith功能)

前言:很多时候,一些不知道啥进程,把你的文件给占用了,然后就没办法删掉或者做其他操作。如果使用Locksmith功能,就可以实现快速锁定是哪个进程在搞事情,把对应进程干掉就可以了。下面内容演示C#使用...

小材大用!用好Windows 10文件缩略图

当我们将图片传输到电脑中后,默认情况下Windows会显示小图预览,因此我们可以不打开图片就能看到图的基本模样。为了防止系统负担过重,Windows只在打开特定的文件夹时生成缩略图,且在系统关机时缩略...

C#:删除 Word 中的页眉或页脚_c# 删除文件

C#:删除Word中的页眉或页脚在处理Word文档批量操作时,我们经常需要清除页眉页脚——比如合并文档后去除冗余信息,或为标准化报告格式。手动操作不仅繁琐,更难以集成到自动化流程中。使用Spire...

C# INI文件读写方法_c#ini文件如何一次读取所有数据

在C#项目的开发实践里,存在着一种十分常见且实用的操作习惯,那就是把一部分常用的参数值写入到.ini文件当中。这种做法背后有着充分的考量。从软件系统的设计角度来看,将常用参数集中存放在.ini文件...

C# 基础知识系列- 14 IO篇 文件的操作(1)

0.前言本章节是IO篇的第二集,我们在上一篇中介绍了C#中IO的基本概念和一些基本方法,接下来我们介绍一下操作文件的方法。在编程的世界中,操作文件是一个很重要的技能。...

C# 删除 Excel 工作表中的空白行和空白列

在日常处理Excel数据时,经常会遇到表格中夹杂着许多空白行或空白列。这些空白内容不仅影响数据的整洁性,还可能导致数据处理和分析结果出错。手动逐一删除这些空白行列不仅效率低下,而且容易遗漏。本文将...

微信小程序原生开发【辅助框架】 LWX

项目介绍作者开发了一年多的小程序,在开发过程中遇到了很多的坑与不方便之处,同时又对原生开发有着一定的执著,但是对于习惯了我这种用惯了vue的人来说,原生小程序中的一些写法确实让人感到难受,我想大家在进...

谷歌正式发布Android 12,UI更好看,打造属于自己的定制化属性

焕然一新的Android12今年5月的GoogleI/O大会上,谷歌推出了Android12系统,这是原生安卓系统史上最大的设计变化,从此旧貌换新颜。...

【推荐】一个基于 SpringBoot 框架开发的 OA 办公自动化系统

如果您对源码&技术感兴趣,请点赞+收藏+转发+关注,大家的支持是我分享最大的动力!!!项目介绍...

「干货」9个最热门React PC端组件库|UI框架

最近一直在使用React.js开发项目,在开发过程中也用到了一些开源UI组件库。上次有给大家分享React移动端组件库,今天,就给大家推荐9个常用ReactPC端组件库。...

Android主流UI开源库整理_android ui 布局开源框架

前言最近老大让我整理一份Android主流UI开源库的资料,以补充公司的Android知识库。由于对格式不做特别限制,于是打算用博客的形式记录下来,方便查看、防丢并且可以持续维护、不断更新。标题隐...

Datetimepicker.js用法_datepicker的用法

$('.form_date').datetimepicker({//初始化language:'zh-CN',//weekStart:1,...

取消回复欢迎 发表评论: