Vue3+Element Plus backend management system from scratch (10) - Custom watermark instructions and global registration

In actual project development, custom instructions are often used, such as: copy and paste, input box anti-shake, input box prohibition of special characters, permission verification, background watermark, drag and drop, etc...

Command is indeed an elegant existence.

For detailed instructions on defining a common custom directive in Vue3, please see the official website: https://cn.vuejs.org/guide/reusability/custom-directives.html

A custom directive is defined by an object that contains similar component lifecycle hooks. The hook function receives the element to which the instruction is bound as its parameter.

Custom directive optional hook

const myDirective = {
    
    
  // 在绑定元素的 attribute 前
  // 或事件监听器应用前调用
  created(el, binding, vnode, prevVnode) {
    
    
    // 下面会介绍各个参数的细节
  },
  // 在元素被插入到 DOM 前调用
  beforeMount(el, binding, vnode, prevVnode) {
    
    },
  // 在绑定元素的父组件
  // 及他自己的所有子节点都挂载完成后调用
  mounted(el, binding, vnode, prevVnode) {
    
    },
  // 绑定元素的父组件更新前调用
  beforeUpdate(el, binding, vnode, prevVnode) {
    
    },
  // 在绑定元素的父组件
  // 及他自己的所有子节点都更新后调用
  updated(el, binding, vnode, prevVnode) {
    
    },
  // 绑定元素的父组件卸载前调用
  beforeUnmount(el, binding, vnode, prevVnode) {
    
    },
  // 绑定元素的父组件卸载后调用
  unmounted(el, binding, vnode, prevVnode) {
    
    }
}

hook parameters

The hook of the command will pass the following parameters:

  • el: The element to which the directive is bound. This can be used to directly manipulate the DOM.

  • binding: An object containing the following properties.

    • value: The value passed to the instruction. For example, in v-my-directive="1 + 1", the value is 2.
    • oldValue: Previous value, only available in beforeUpdate and updated. It is available whether the value changes or not.
    • arg: Parameters passed to the command (if any). For example, in v-my-directive:foo, the parameter is "foo".
    • modifiers: An object containing modifiers (if any). For example, in v-my-directive.foo.bar, the modifier object is { foo: true, bar: true }.
    • instance: The component instance using this directive.
    • dir: The definition object of the instruction.
  • vnode: Represents the underlying VNode of the bound element.

  • prevNode: The VNode representing the element to which the directive is bound in the previous rendering. Available only in beforeUpdate and updated hooks.


The following is an example of a custom instruction that adds our custom watermark to the required elements and explains how to register this watermark instruction globally.

Custom watermark command

I just learned canvas yesterday, and I just happened to practice using the watermark command. The main ideas are:

  1. Generate a canvas canvas
  2. Draw the watermark on canvas,
  3. Add the background-image attribute to the element that needs to be added with a watermark. The attribute value is base64 generated through canvas.
Preparation

First create a new directive folder in src

image.png

watermark.ts is the watermark instruction code
index.ts is the unified export of instructions

watermark.ts
import {
    
     DirectiveBinding } from 'vue'

// 水印
export default {
    
    
  mounted(el: HTMLElement, binding: DirectiveBinding) {
    
     
    let txt = 'hello world'
    let style = {
    
    }
    if (binding && binding.value) {
    
    
      txt = binding.value.txt
      style = binding.value.style
    }
    genWatermark(el, txt, style)
  }
}

interface CanvasTextStyle {
    
    
  font?: string
  color?: string
}

function genWatermark(el: HTMLElement, txt: string, style?: CanvasTextStyle) {
    
    
  const defaultStyle = {
    
    
    font: '14px arial',
    color: 'rgba(0,0,0,0.2)'
  }

  let canvas = <HTMLCanvasElement>document.createElement('canvas')
  let ctx = <CanvasRenderingContext2D>canvas.getContext('2d')

  ctx.translate(150, 75)
  ctx.rotate((Math.PI / 180) * 25)
  ctx.translate(-150, -75)

  ctx.font = style?.font || defaultStyle.font
  ctx.fillStyle = style?.color || defaultStyle.color
  ctx.textAlign = 'center'
  ctx.textBaseline = 'middle'

  ctx.fillText(txt, canvas.width / 2, canvas.height / 2)

  el.style.backgroundImage = `url(${
      
      canvas.toDataURL('image/png')})`
}

Global registration directive

For ease of use, we choose to register the watermark command globally.

First, export it uniformly through index.ts

directive/index.ts

import {
    
     App } from 'vue'
import color from './color'
import watermark from './watermark'

export default (app: App) => {
    
    
  app.directive('color', color)
  app.directive('watermark', watermark)
}

Import in main.ts

import App from './App.vue'
const app = createApp(App)

...

// 注册指令
import directive from './directive'
directive(app)

app.mount('#app')

Finally, in the component use


    <div  v-watermark></div>
    
    <div      
      v-watermark="{
        txt: 'mocha vue3 system',
        style: {
          font: '10px gothic',
          color: 'rgba(255,80,0,0.5)'
        }
      }"
    ></div>

The final product is still a little different from the desired effect. Unfortunately, I am not good at canvas, so I can only arrange them neatly like this.

image.png

Of course, one command cannot meet the needs. Next, more common commands will be added to this project. What other commands do you think are very useful?

More Vue3 custom instructions

# Element Plus’ table el-table is highly adaptive

Guess you like

Origin blog.csdn.net/immocha/article/details/130681243