Explanation and example usage of 4 custom instructions in Vue

Explanation and example usage of 4 custom instructions in Vue

Four practical vue custom instructions

1. v-drag

Requirement: Mouse drag element

Ideas:

Element offset = coordinates after mouse sliding - coordinates when the mouse initially clicks the element + top and left distance of the element from the visible area at the time of initial click.
Use the visible area as the boundary and restrict dragging within the visible area. [Recommended: "Vue.js Tutorial"]

Code:

Vue.directive('drag', {
  inserted(el) {
    let header = el.querySelector('.dialog_header')
    header.style.cssText += ';cursor:move;'
    header.onmousedown = function (e) {
      //Get the width and height of the current visible area let clientWidth = document.documentElement.clientWidth
      let clientHeight = document.documentElement.clientHeight
 
      //Get its own width and height let elWidth = el.getBoundingClientRect().width
      let elHeight = el.getBoundingClientRect().height
 
      //Get the top and left of the current distance visible area
      let elTop = el.getBoundingClientRect().top
      let elLeft = el.getBoundingClientRect().left
 
      //Get the coordinates when clicking let startX = e.pageX
      let startY = e.pageY
 
      document.onmousemove = function (e) {
        //Element offset = coordinates after mouse sliding - coordinates when mouse initially clicks element + top and left distance of element from visible area at initial click
        let moveX = e.pageX - startX + elLeft
        let moveY = e.pageY - startY + elTop
 
        //Use the visible area as the boundary and limit dragging within the visible area if ((moveX + elWidth) > clientWidth || moveX < 0 || (moveY + elHeight) > clientHeight || moveY < 0) {
          return
        }
 
        el.style.cssText += 'top:' + moveY + 'px;left:' + moveX + 'px;'
      }
      document.onmouseup = function () {
        document.onmousemove = null
        document.onmouseup = null
      }
    }
  }
})

2. v-wordlimit

Requirements: The background field has a length limit and distinguishes between Chinese and English. Chinese is two bytes and English is one byte. Therefore, the input box needs to limit the number of characters entered and distinguish the number of bytes, and the number of characters entered needs to be echoed.

Ideas:

One-byte regular expression /[\x00-\xff]/g

Create an element that wraps the word limit and position it on the textarea and input box

Calculate the number of input characters, enLen for one-byte characters and cnLen for two-byte characters; this is used for string truncation processing later.

When the number of characters input exceeds the limit, truncation is performed; substr(0,enLen+cnLen)

The interface updates the value of the input box, or initializes the value of the input box, and needs to echo the correct number of bytes

Code:

Vue.directive('wordlimit',{
  bind(el,binding){
    console.log('bind');
    let { value } = binding
    Vue.nextTick(() => {
      //Find out whether the input box is a textarea box or an input box let current = 0
      let arr = Array.prototype.slice.call(el.children)
      for (let i = 0; i < arr.length; i++) {
        if(arr[i].tagName=='TEXTAREA' || arr[i].tagName=='INPUT'){
          current = i
        }
      }
   
      //Update the number of bytes in the current input box el.children[el.children.length-1].innerHTML = el.children[current].value.replace(/[^\x00-\xff]/g,'**').length +'/'+value//eslint-disable-line
    })
  },
  update(el,binding){
    console.log('update');
    let { value } = binding
    Vue.nextTick(() => {
      //Find out whether the input box is a textarea box or an input box let current = 0
      let arr = Array.prototype.slice.call(el.children)
      for (let i = 0; i < arr.length; i++) {
        if(arr[i].tagName=='TEXTAREA' || arr[i].tagName=='INPUT'){
          current = i
        }
      }
   
      //Update the number of bytes in the current input box el.children[el.children.length-1].innerHTML = el.children[current].value.replace(/[^\x00-\xff]/g,'**').length +'/'+value//eslint-disable-line
    })
  },
  inserted(el,binding){
    console.log('inserted');
    let { value } = binding
 
    //Find out whether the input box is a textarea box or an input box let current = 0
    let arr = Array.prototype.slice.call(el.children)
    for (let i = 0; i < arr.length; i++) {
      if(arr[i].tagName=='TEXTAREA' || arr[i].tagName=='INPUT'){
        current = i
      }
    }
 
    //Create an element that wraps the word limit and positions it on the textarea and input box let div = document.createElement('div')
    if(el.children[current].tagName=='TEXTAREA'){//It is textarea, positioned in the lower right corner div.style = 'color:#909399;position:absolute;font-size:12px;bottom:5px;right:10px;'
    }else{
      let styStr = ''
      if(!el.classList.contains('is-disabled')){//If the input box is not grayed out, add background color styStr = 'background:#fff;'
      }
      div.style = 'color:#909399;position:absolute;font-size:12px;bottom:2px;right:10px;line-height:28px;height:28px;'+styStr
    }
 
    div.innerHTML = '0/' + value
    el.appendChild(div)
    el.children[current].style.paddingRight = '60px'
 
    el.oninput = () => {
      let val = el.children[current].value
      val = val.replace(/[^\x00-\xff]/g,'**') //eslint-disable-line
      // The word limit box is inserted into el as the last element el.children[el.children.length-1].innerHTML = val.length + '/' + value
      if(val.length>value){
        let cnLen = 0 //Number of one-byte words let enLen = 0 //Number of two-byte words if(val.match(/[^**]/g) && val.match(/[^**]/g).length){
          enLen = val.match(/[^**]/g).length // Calculate the number of words in a byte // A byte has both bytes if((value - val.match(/[^**]/g).length)>0){
            cnLen = Math.floor((value - val.match(/[^**]/g).length)/2)
          }else{
            cnLen = 0
          }
        }else{ //For both bytes enLen = 0
          cnLen = Math.floor(value/2)
        }
 
        if(enLen>value){
          enLen = value
        }
 
        //If the number of bytes exceeds the limit, intercept el.children[current].value = el.children[current].value.substr(0,enLen+cnLen)
 
        //Update the number of bytes in the current input box el.children[el.children.length-1].innerHTML = el.children[current].value.replace(/[^\x00-\xff]/g,'**').length +'/'+value//eslint-disable-line
 
      }
    }
 
  },
})

use:

<el-input type="textarea" rows="3" v-wordlimit="20" v-model="value"></el-input>

3. v-anthor

Requirement: Click an element (usually a title, subtitle, etc.) and the animation scrolls to the corresponding content block

Ideas:

Timer using window.scrollBy

If you don't consider IE, you can directly use window.scrollBy({ top: ,left:0,behavior:'smooth' })

Code:

Vue.directive('anchor',{
  inserted(el,binding){
    let { value } = binding
    let timer = null
    el.addEventListener('click',function(){
      // The distance between the current element and the top of the visible area let currentTop = el.getBoundingClientRect().top
      animateScroll(currentTop)
    },false)
     
    function animateScroll(currentTop){
      if(timer){
        clearInterval(timer)
      }
      let c = 9
      timer = setInterval(() => {
        if(c==0){
          clearInterval(timer)
        }
        c--
        window.scrollBy(0,(currentTop-value)/10)
      },16.7)
    }
 
  }
})

use:

<div class="box" v-anchor="20" style="color:red;">Yes</div>

4. v-hasRole

Requirements: Add or delete corresponding elements according to system roles

Code:

Vue.directive('hasRole',{
  inserted(el,binding){
    let { value } = binding
    let roles = JSON.parse(sessionStorage.getItem('userInfo')).roleIds
 
    if(value && value instanceof Array && value.length>0){
 
      let hasPermission = value.includes(roles)
 
      if(!hasPermission){
        el.parentNode && el.parentNode.removeChild(el)
      }
    }else{
      throw new Error(`Please check the expression bound to the instruction, the correct format is such as v-hasRole="['admin','reviewer']"`)
    }
  }
})

This concludes this article about the explanation and example usage of 4 custom instructions in Vue. For more information about the 4 custom instructions in Vue that are worth knowing, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Use of vue global custom instructions and local custom instructions
  • Detailed code about Vue custom instructions to implement element dragging
  • How to write a custom directive for Vue3
  • vue3 custom directive details
  • Detailed explanation of Vue custom instructions
  • Description of vue custom directives and their common hook functions

<<:  How to use HTML form with multiple examples

>>:  How to center the entire page content so that the height can adapt to the content and automatically expand

Recommend

Tips for importing csv, excel or sql files into MySQL

1. Import csv file Use the following command: 1.m...

How to use VirtualBox to build a local virtual machine environment on Mac

1. Big Data and Hadoop To study and learn about b...

Search engine free collection of website entrances

1: Baidu website login entrance Website: http://ww...

Solve the problem that the IP address obtained using nginx is 127.0.0.1

Get ip tool import lombok.extern.slf4j.Slf4j; imp...

Example code for implementing anti-shake in Vue

Anti-shake: Prevent repeated clicks from triggeri...

A brief discussion on the magic of parseInt() in JavaScript

cause The reason for writing this blog is that I ...

Design theory: the basics of font design

<br />Words are the inevitable product of hu...

js to realize web message board function

This article example shares the specific code of ...

Example of how to implement keepalived+nginx high availability

1. Introduction to keepalived Keepalived was orig...

How to separate static and dynamic state by combining Apache with Tomcat

Experimental environment Apache and Tomcat are bo...

Detailed steps to build a file server in Windows Server 2012

The file server is one of the most commonly used ...