⏳ preface

This is the 25th day of my participation in Gwen Challenge

After recently learning about vue3’s new features on Monday, I thought I’d try out some new gadgets with vue3. I suddenly thought of a problem I had encountered before, I wanted to get the current mouse click position, but I used to write directly with native JS, so the experience was not so good, so today I started my small tool journey with vue3!

In today’s article, I’ll walk you through the process of initializing a VUe3 project and implementing a mouse tracker and asynchronous load component with VUe3.

🎬 🎬 🎬

🖱️ mouse tracker

1. Function realization

We will first create a TS file under the vue3 project. This TS file is used to implement the mouse tracker function. The specific code is as follows:

// Introduce the Composition API you need to use
import { ref, onMounted, onUnmounted } from 'vue'
// Implement mouse tracker function
function useMousePosition(){
    
    // Initialize the x and y values
    const x = ref(0)
    const y = ref(0)
    
    // Get the X-axis and Y-axis values after the mouse click
    const updateMouse = (e: MouseEvent) = > {
      x.value = e.pageX
      y.value = e.pageY
    }
	
    // Execute updateMouse on mouse click
    onMounted(() = > {
      document.addEventListener('click', updateMouse)
    })
	
    // Execute the destruction operation on the current click event after the mouse click ends
    onUnmounted(() = > {
      document.removeEventListener('click', updateMouse)
    })
	
    // Return x and y values
    return {x, y}
}

// Export the function
export default useMousePosition
Copy the code

2. Bind static pages

We create a.vue file under the vue3 project to load the static component content. The specific code is as follows:

<template>
  <div id="app">
    <h1>Mouse tracker</h1>
    <h1>X:{{x}},Y:{{y}}</h1>
  </div>
</template>

<script lang="ts">
// Introduce the function
import useMousePosition from './useMousePosition'

export default{
  name: 'App'.setup(){
    
    // Reference the value returned by the function
    const { x, y } = useMousePosition()
	
    / / the return value
    return{
      x,
      y
    }
  }
};
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

Copy the code

Finally, let’s look at the display:

With that in mind, let’s take a look at the code. As you can see, the code in VUe3 is pulled away, making it very easy to implement functionality. Instead of putting the specific functionality inside the component, we implement it by defining a TS file outside the component.

In a way, the code is much more extensible and maintainable.

2. ⚙️ asynchronously load components

After looking at the mouse tracker, let’s implement an asynchronous load component.

In our daily development, we often need to use asynchronous loading components, and the most common requirement of asynchronous loading is loading loading state.

The state of loading loading is that when the page is loaded, if the content of the asynchronous request is not displayed, a loading effect will be displayed and the user will wait until the content of the asynchronous request is loaded.

So let’s implement this.

1. Function realization

Let’s start by creating a TS file under the VUe3 project. This TS file is used to load asynchronous components. The specific code is as follows:

import { ref } from 'vue'
import axios from 'axios'

function useURLLoader(url: string){
    const result = ref(null)
    const loading = ref(true)
    const loaded = ref(false)
    const error = ref(null)

    axios.get(url).then((rawData) = > {
        loading.value = false
        loaded.value = true
        result.value = rawData.data
    }).catch(e= > {
        error.value = e
        loading.value = false
    })

    return{
        result,
        loading,
        loaded,
        error
    }
}

export default useURLLoader
Copy the code

Now that the functionality is complete, we’ll bind the asynchronous functionality to the static page.

2. Bind static pages

Here’s a free API available online at dog. CEO /dog-api/. This API is a dog API that can fetch image data in real time. The specific usage is as follows:


Next we create a.vue file under the vue3 project to load the static component content. The specific code is as follows:

<template>
  <div id="app">
    <h1>Asynchronously loading components</h1>
    <button v-if="loading">Loading...</button>
    <img v-if="loaded" :src="result.message">
  </div>
</template>

<script lang="ts">
import useURLLoader from './useUrlLoader'

export default{
  name: 'App'.setup(){
    
    const { result, loading, loaded, error } = useURLLoader('https://dog.ceo/api/breeds/image/random')
    
    return{
      result,
      loading,
      loaded,
      error
    }
  }
};
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

Copy the code

Finally, let’s look at the display:

As you can see, when we refresh, the data of asynchronous request has not been loaded, so Loading will be displayed first, and then the specific data will be displayed after the data is loaded. This is the asynchronous Loading component that we often use.

Modify asynchronous component functionality with generics

As we all know, vue2’s support for typescript is very limited, so the update to VUe3 is a huge boost to TS.

In the example above, we got a sense of the extensibility and maintainability of the Composition API, but not content with the status quo, we want to give it another type of enhancement. How?

Based on the above case, we continue to upgrade.

First, we want result to be able to infer the type from generics, so we modify the code for the TS file as follows. The code is as follows:

import { ref } from 'vue'
import axios from 'axios'

// Generics
function useURLLoader<T> (url: string){
    // Result does not have a data type at the beginning
    const result = ref<T | null> (null)
    const loading = ref(true)
    const loaded = ref(false)
    const error = ref(null)

    axios.get(url).then((rawData) = > {
        loading.value = false
        loaded.value = true
        result.value = rawData.data
    }).catch(e= > {
        error.value = e
        loading.value = false
    })

    return{
        result,
        loading,
        loaded,
        error
    }
}

export default useURLLoader
Copy the code

This time we change a cat API, to modify the.vue file. The specific code is as follows:

<template>
  <div id="app">
    <h1>Asynchronously loading components</h1>
    <button v-if="loading">Loading...</button>
    <img v-if="loaded" :src="result[0].url">
  </div>
</template>

<script lang="ts">
import { watch } from 'vue'
import useURLLoader from './useUrlLoader'

interface CatResult{
    id: string;
    url: string;
    width: string;
    height: string;
}

export default{
  name: 'App'.setup(){
    
    const { result, loading, loaded, error } = useURLLoader<CatResult[]>('https://api.thecatapi.com/v1/images/search?limit=1')
   	watch(result, () = > {
        if(result.value){
            console.log('value', result.value[0].url)
        }
    }) 
   
    return{
      result,
      loading,
      loaded,
      error
    }
  }
};
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

Copy the code

The final browser display looks like this:

We can see from our code that modifying a component with generics makes it more extensible. Ts is such a good language who can not love right!

Third, 📚 conclusion

This concludes our tutorial on vuE3 developing mouse trackers and asynchronous loading components! In this article, we learned how to use the new features of VUE3 to implement mouse trackers and asynchronous loading components, and we also used generics and interfaces in TS to transform asynchronous loading components to make them more extensible.

Vue3 keep learning and updating… See you next time! 🥂 🥂 🥂

  • Pay attention to the public number Monday laboratory, the first time to pay attention to learning dry goods, more wonderful columns for you to unlock ~

  • If this article is useful to you, remember to click three times before going oh ~