• 技术文章 >web前端 >Vue.js

    分享五个好用的VueUse函数,一起用起来吧!

    醉折花枝作酒筹醉折花枝作酒筹2021-08-13 18:04:58转载240
    VueUse是Anthony Fu大佬的一个开源项目,它为Vue的开发者提供了大量用于Vue2和Vue3的基本Composition API实用工具函数。

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

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

    VueUse 有哪些实用方法?

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

    将 Vueuse 安装到 Vue 项目中

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

    安装VueUse有两种选择:npm或 CDN

    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 的情况下创建我们的基本组件--使用ref、textarea、以及用于撤销和重做的按钮。

    <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,然后通过 useRefHistory从 text 中提取history、undo和redo属性。

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

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

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

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

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

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

    这是一个简单的组件,使用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 事件。

    bVcTFfK.webp.jpg

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

    我们可以使用useVModel,把它当作一个普通的ref,而不是使用ref并调用props.value和update: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时,我们只需调用.value,useVModel将从我们的组件 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库中我最喜欢的函数之一。它允许我们只用一行就能顺利地在数值之间进行过渡。

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

    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的完整指南。这些只是我平常比较常用的函数,还有很多好用的函数,大家可以自行到官网去学习使用。

    【相关推荐:《vue.js教程》】

    以上就是分享五个好用的VueUse函数,一起用起来吧!的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:segmentfault,如有侵犯,请联系admin@php.cn删除
    专题推荐:前端 css node.js
    上一篇:Vue如何封装Echarts图表 下一篇:教你怎么使用Vue实现动画效果(附代码)
    大前端线上培训班

    相关文章推荐

    • 介绍laravel+vue前后端分离之服务器端配置• 关于electron-vue图片压缩• vue怎么引用css• Vue的响应式原理是什么?• Vue如何封装Echarts图表

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网