preface

This paper records some common utility functions in Vue projects. For unified management of utility functions, these functions are uniformly placed in the utils folder under the SRC directory


1. Custom focus instruction

1. Method 1

Mouted cycle, ref+querySelector gets the input tag, and calls Focus ()

2. Method two

Self-defined directive (local) DIRECTIVES: Fofo (INSERTED), to be used on the label when defined, V-FOFo

3. Method three

Global custom command, recommended (high reuse). Import it from main.js and use it. The code is as follows (example) :

import Vue from 'vue'

Vue.directive("fofo", {inserted(el) {
    // Determine the element name
    if (el.nodeName === 'INPUT' || el.nodeName === 'TEXTAREA') {
      el.focus()
  	} else {
     // Try to fetch from the inner layer
      el.querySelector('input').focus()
    }
  }
})
Copy the code

Two, the input box shake

1, requirements,

When users input content in the input box, to get the input content back to the server, it needs to listen to the input event of the input box, but when the value of the input box changes, it immediately sends an Ajax request, which will cause some unnecessary Ajax requests. When the user stops typing and waits for a certain amount of time before sending a request to the background, some unnecessary requests can be reduced.

2, train of thought

When the user starts typing, a timer starts, and if the user does not enter again after the timer ends, an Ajax request is sent to the background. If the user enters again within the specified time, the last timer will be cleared and the timer will be reset.

3. Code implementation

Here’s an example of how you can pull the code out once you understand how it works. The code is as follows (example) :

<template>
	<div>
        <input type="text" v-model="kw" @input="inputFn"/>
    </div>
</template>
<script>
export default{
    data() {return{
            kw:' ',
            timer:null
        }
    },
    methods:{
        inputFn(){
            clearTimeout(this.timer)
      		this.timer = setTimeout(() => {
                if(this.kw === ' ') returnConsole. log(this.kw)}, 1000) // The logic in the timer will be executed when the user stops typing for a second. }}} </script>Copy the code

Three, keyword highlighting

1, requirements,

When the user searches for a keyword in the input box, the keyword in the association list displayed will change the color, so that the user can see the desired result more intuitively.

2, train of thought

Encapsulates a lightFn function that takes two arguments, the first to the string being modified and the second to the keyword to match

3. Code demonstration

The code is as follows (example) :

export const lightFn = (str, targetStr) = > {
    // Ignore case and match globally
  const reg = new RegExp(targetStr, 'ig')
  return str.replace(reg, match= > {
    return `<span style="color:red">${match}</span>`})}Copy the code

Format the time stored in the Excel table

1, requirements,

Convert the time stored in the Excel table to be imported from the Excel format to the format when the time is saved.

2. Code demonstration

This code is from Blue Rain Creek, thanks to the big guy, here is the code below (example) :

export function formatExcelDate(numb, format = '/') {
  const time = new Date((numb - 25567) * 24 * 3600000 - 5 * 60 * 1000 - 43 * 1000 - 24 * 3600000 - 8 * 3600000)
  time.setYear(time.getFullYear())
  const year = time.getFullYear() + ' '
  const month = time.getMonth() + 1 + ' '
  const date = time.getDate() + ' '
  if (format && format.length === 1) {
    return year + format + month + format + date
  }
  return year + (month < 10 ? '0' + month : month) + (date < 10 ? '0' + date : date)
}
Copy the code

Five, custom command control button level permissions

1. The demand

Vue project with elementUI as a background management system, users with different permissions, see different pages and can use different functions. Functions are realized by clicking links or buttons, and functions are not displayed when users do not have corresponding permissions. Let’s see how to control the creation of buttons through custom commands

2. Code demonstration

  • Array methods

Array.includes() this method is used to determine whether the values passed in parentheses exist in the Array, returning true if they do and false if they do.

  • In the custom instruction,binding.valueYou can get the value passed in where the custom directive is used.
// Register a global custom directive 'V-allow'
Vue.directive('allow', {
  inserted: function(el, binding) {
     // Get the list of permissions the user has
    // If the user has permission for this item
    ifUser has permissions. Includes (binding.value) {// console.log(' determine if this element will be displayed ', el, binding.value)
    } else {
       // If the user does not have this permission, delete the element
      el.parentNode.removeChild(el)
      // It is not safe to use display
      // el.style.display = 'none'}}})Copy the code

Used in.vue files, custom directives need to be passed in strings

<template>
  <div>
  	<el-button
      v-allow="'xxx'"
      type="warning"
      @click="doSomeThing"</el-button> </div> </template>Copy the code

Vue3 custom instruction — lazy loading of pictures

1. The train of thought

Use a webAPI: IntersectionObserver MDN document: IntersectionObserver

The IntersectionObserver() constructor creates and returns a IntersectionObserver object. If rootMargin is specified it is checked for syntax, thresholds are checked to ensure that all are between 0.0 and 1.0, and the list of thresholds is sorted in ascending order. If the threshold list is empty, it defaults to an array of [0.0].

callback

  • When the percentage of elements visible exceeds a specified threshold, a callback function is called that takes two arguments:
  1. entries

A IntersectionObserverEntry object array, each threshold is triggered, are more or less have deviation with a specified threshold.

  1. observer

IntersectionObserver instance to be invoked.

  • Use the API to monitor whether the image is in the viewable area
  • When the picture appears in the viewport, give the picturesrcAttribute assignment
// Create the observed object instance
// const observer = new IntersectionObserver(callback[, options])

const obs = new IntersectionObserver(([{isIntersecting}], observer) = > {
    // entries = [{isIntersecting: true}]
    
}, {})
// Listen for DOM elements
obs.observe(imgDom)
// Cancel DOM listening
obs.unobserve(imgDom)

// Callback is triggered when the DOM enters and leaves the viewable area
// - Two callback parameters entries, observer
// - entries Array of observed element information objects [{element information},{}], where isIntersecting determines whether to enter or leave
// - observer is an example of an observation
// options Configures parameters
// - Three configuration attributes root rootMargin threshold
// - root Indicates the scrolling container. The default is document
// -rootMargin Indicates whether the container has a margin
// - threshold Indicates the crossover ratio

The instance provides two methods
// Observe (dom) Observe which DOM
// unobserve(dom) stop looking at that DOM
Copy the code

2. Code demonstration

Vue plug-in is used here to encapsulate global custom instructions

// Import an image that was loaded successfully, but was displayed to the user with the image address error
import defaultImg from '@/assets/images/xxx.png'
/ / instructions
const defineDirective = (app) = > {
  // Image lazy loading command
  app.directive('lazyload', {
    mounted (el, binding) {
      const observer = new IntersectionObserver(([{ isIntersecting }]) = > {
        if (isIntersecting) {
          observer.unobserve(el)
          el.onerror = () = > {
              el.src = defaultImg
          }  
          el.src = binding.value
        }
      }, {
        threshold: 0.01
      })
      observer.observe(el)
    }
  })
}

export default {
  install (app) {
    defineDirective(app)
  }
}
Copy the code

Introduced in main.js

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
// Import a custom directive that encapsulates itself
import myUI from './xxx'

createApp(App).use(store).use(router).use(myUI).mount('#app')

Copy the code

Use 3.

Replace the SRC attribute on the img tag with v-lazyload if you need lazy image loading in the.vue end file.

Vue3 batch registration components

1. The train of thought

  • userequireProvided functionscontextLoads all files in a directory.vueFile with suffix.
  • thencontextThe function returns an import functionimportFn
    • It has a propertykeys() Get all file paths
  • Through the file path array, through the number array, and then useimportFnImport component objects by path
  • Do global registration while traversing

2. Code demonstration

// Vue plugin extends vue functionality, global components, directives, functions (vue.30 unfilter)
Install is executed when you import in mian.js and use vue.use () (vue3.0 app)
// Import all components under the specified folder folder
Context (dir,deep,matching)
// Parameters: 1. Directory 2. Whether to load subdirectories (true: load; false: not load) 3. Loaded re matches
const importFn = require.context('/'.false./\.vue$/)
// console.dir(importfn.keys ()) file name array

export default {
  install (app) {
      // Batch register global components
      importFn.keys().forEach(key= > {
      // Import components
      const component = importFn(key).default
      // Register the component
      app.component(component.name, component)
    })
  }
}
Copy the code

conclusion

Come across useful tool function will continue to update, if you feel useful, remember to like the collection oh ~