By Matt Maribojoc

Have a dream, have dry goods, wechat search [big move world] pay attention to this in the wee hours of the morning is still brushing the dishes of the wisdom.

In this paper, making github.com/qq449245884… Has been included, there are a line of big factory interview complete test points, information and my series of articles.

VueUse, an open source project by Anthony Fu, provides Vue developers with a number of basic Composition API utility functions for Vue2 and Vue3.

It has dozens of solutions for common developer use cases, such as tracking REF changes, detecting element visibility, simplifying common Vue patterns, keyboard/mouse input, and more. This is a great way to really save development time because we don’t have to add all these standard features ourselves, just take them and use them (thanks again).

I like the VueUse library because it really puts the developer first when deciding which utilities to provide, and it’s a well-maintained library because it keeps pace with the current version of Vue.

What are the practical methods of VueUse?

If you want to see a complete list of each utility, I suggest you check out the official documentation. But to summarize, there are nine types of functions in VueUse.

  • Animation – Includes easy to use transitions, timeouts, and timings

  • Browser – Can be used for different screen controls, clipboard, preferences, and so on

  • Component – Provides shorthand for different Component methods

  • Sensors – for listening for different DOM events, input events and network events

  • State – Manages user State (global, local storage, session storage)

  • Utility — different Utility methods such as getters, conditionals, ref synchronization, etc.

  • Watch – more advanced types of observers, such as pauseable observers, abandoned observers, and conditional observers

  • Others – different types of functionality for events, WebSockets, and Web Workers

Install Vueuse into the Vue project

One of the biggest features of the VueUse is that it is compatible with Vue2 and Vue3 in just one package!

There are two options for installing VueUse: NPM or CDN

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

NPM is recommended because it is easier to understand, but if we use a CDN, we might access it through window.vueuse.

Using NPM, you can get the desired method by deconstructing:

import { useRefHistory } from '@vueuse/core'
Copy the code

UseRefHistory tracks changes in reactive data

UseRefHistory keeps track of every change made to ref and stores it in an array. This enables us to easily provide undo and redo functionality to the application.

Look at an example where we make a text area that can be undone

The first step is to create our base components — using refs, textareas, and buttons for undo and redo — without VueUse.

<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>
Copy the code

Next, import useRefHistory and extract the History, undo, and redo attributes from the text using useRefHistory.

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

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

Every time our REF changes and updates the history property, a listener is fired.

To see what’s going on at the bottom, let’s print out the history content. The undo and redo functions are invoked when the corresponding button is clicked.

<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>
Copy the code

Direct, run, and the effect is as follows:

There are also different options to add more functionality to this feature. For example, we can drill down to the reactive object and limit the number of history records like this.

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

OnClickOutside close the modal

OnClickOutside detects any clicks outside an element. In my experience, the most common use of this feature is to close any mode or pop-up window.

Usually, we want our modal to block the rest of the web page to catch the user’s attention and limit errors. However, if they do click outside the mode, we want it to be off.

To do this, there are only two steps.

  • Create a template reference for the element to be detected
  • Using this templaterefrunonClickOutside

This is a simple component that uses the onClickOutside pop-up window.

<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; } </styleCopy the code

As a result, we can open the popup window with our button, and then close it by clicking outside the popup content window.

UseVModel simplifies v-Model binding.

A common use case for Vue developers is to create a custom V-Model binding for a component. This also requires our component to accept a value as a prop and issue an Update event to the parent whenever this value is changed.

The useVModel function reduces this to using only the standard ref syntax. Suppose we have a custom text input and try to create a V-Model for the value of its text input. Normally, we must accept a prop of value and then issue a change event to update the data value in the parent component.

Instead of using ref and calling props. Value and update:value, we can use useVModel as if it were a normal ref. This helps reduce the number of different grammars we need to remember!

<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>
Copy the code

Whenever we need to access value, we just call.value, and useVModel will give us the value from our component props. Whenever the value of an object changes, the useVModel issues an update event to the parent.

Here is a simple example of a parent component

<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
    }
  }
}
Copy the code

As a result, the parent’s value is always synchronized with the child’s input:

The visibility of elements is tracked using IntersectionObserver

The useIntersectionObserver is very powerful when determining whether two elements overlap. A good use case for this is to check whether an element is currently visible in the viewport.

Basically, it checks the percentage that the target element intersects with the root element/document. If this percentage exceeds a certain threshold, it calls a callback to determine whether the target element is visible.

UseIntersectionObserver provides a simple syntax for using the IntersectionObserver API. All we need to do is provide a template ref for the element we want to check.

By default, IntersectionObserver is based on the viewport of the document, with a threshold of 0.1– so when this threshold is crossed in any direction, our IntersectionObserver will be triggered.

Example: We have a false paragraph that just takes up space in our viewport, the target element, and then a print statement that prints the visibility of our element.


<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>
Copy the code

After running, the corresponding values are updated:

We can also specify more options for our Intersection Observer, such as changing its root element, margin (the offset to the root bounding box when calculating the Intersection), and threshold level.

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,})Copy the code

Just as importantly, this method returns a stop function, which we can call to stop looking at the intersection. This is especially useful if we only want to track the first time an element is visible on the screen.

In this code, once targetIsVisible is set to true, the observer stops and our value remains true even if we scroll away from the target element.

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

Use The useTransition to create a digital loading animation

UseTransition is one of my favorite functions in the entire VueUse library. It allows us to smoothly transition between values with just one row.

If I use useTransition to create an effect like this, what do I do?

We can do this in three steps.

  • Initialize a ref variable count with an initial value of 0

  • Use useTransition to create a variable called output

  • Change the value of 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>
Copy the code

Then display the output value in the template:

<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>
Copy the code

Running result:

We can also convert an entire array of numbers using useTransition. This is useful when using position or color. A good technique for using colors is to use computed properties to format the RGB values into the correct color syntax.

<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>
Copy the code

conclusion

This is not a complete guide to VueUse. These are just my usual more commonly used functions, there are many useful functions, you can go to the official website to learn to use.

~ over, I went to brush the dishes, weekends do not brush the dishes, night kneeling durian.

The possible bugs after the deployment of code can not be known in real time, in order to solve these bugs, spent a lot of time log debugging, here by the way to recommend you a good BUG monitoring toolFundebug.

Original text: learvue co / 2021/07/5 – v…

communication

Have a dream, have dry goods, wechat search [big move world] pay attention to this in the wee hours of the morning is still brushing the dishes of the wisdom.

In this paper, making github.com/qq449245884… Has been included, there are a line of big factory interview complete test points, information and my series of articles.