关于javascript:VueUse中的这5个函数也太好用了吧

0次阅读

共计 7882 个字符,预计需要花费 20 分钟才能阅读完成。

作者:Matt Maribojoc
译者:前端小智
起源:medium

有幻想,有干货,微信搜寻 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。

本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试残缺考点、材料以及我的系列文章。

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 的残缺指南。这些只是我平时比拟罕用的函数,还有很多好用的函数,大家能够自行到官网去学习应用。

~ 完,我去刷碗了,周末不刷碗,早晨跪榴莲。

代码部署后可能存在的 BUG 没法实时晓得,预先为了解决这些 BUG,花了大量的工夫进行 log 调试,这边顺便给大家举荐一个好用的 BUG 监控工具 Fundebug。

原文:https://learvue.co/2021/07/5-…

交换

有幻想,有干货,微信搜寻 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。

本文 GitHub https://github.com/qq44924588… 已收录,有一线大厂面试残缺考点、材料以及我的系列文章。

正文完
 0