Some time ago, when I was developing H5 page with the framework, I came across a built-in attribute in the framework to adapt to the abnormity screen. Although it was realized internally by the component, this approach gave me an idea: could I write a attribute to achieve such a function?

After some reflection, I realized that Vue’s directive pattern is similar to the way attributes are written. In Vue, we do a lot of work with template directives such as V-if V-for, and Vue also supports custom attributes:

const app = Vue.createApp({})
// Register a global custom directive 'V-focus'
app.directive('focus', {
  // When the bound element is mounted into the DOM...
  mounted(el) {
    // Focus elements
    el.focus()
  }
})
Copy the code

You can then use the new V-focus attribute on any element in the template, as shown below

<input v-focus />
Copy the code

Note: in addition to global registration, you can also use local registration. In practical development, you can use another convenient function of Vue mixin to mix the corresponding instructions into the file you want to use, in order to achieve code reuse, so start to get down to business.

Bottom safety zone fit

First, the page must add the meta tag to the head tag and set viewport-fit=cover

directives: {
    safeAreaBottom: {
      bind(el, binding) {
        const addHigh = binding.value || 0
        el.setAttribute('style', el.style.cssText + `padding-bottom: calc(${addHigh}+ constant(safe-area-inset-bottom)); padding-bottom: calc(${addHigh}+ env(safe-area-inset-bottom)); `); }}}Copy the code

Use:

<div v-safe-area-bottom></div>
Copy the code

If the design itself has a margin, it can be dynamically adapted:

<div v-safe-area-bottom="'1rem'"></div>
<div v-safe-area-bottom="'10px'"></div>
Copy the code

Is it convenient? Let’s take a look at another mobile terminal H5 will encounter problems, and again with the Vue command to solve it.

Popover background page does not scroll

In mobile terminal development, when the page pops up the scroll window, the background page needs to be fixed, otherwise there will be “scroll through” phenomenon.

touchScroll: {
  inserted() {
    const scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
    document.body.style.cssText += 'position:fixed; width:100%; top:-' + scrollTop + 'px; ';
  },
  unbind() {
    const body = document.body || document.documentElement;
    body.style.position = ' ';
    const top = body.style.top;
    document.body.scrollTop = document.documentElement.scrollTop = -parseInt(top, 10);
    body.style.top = ' '; }}Copy the code
<div v-touch-scroll>Yes, I'm a popover, and my background freezes when I show up</div>
Copy the code

Implement a copy tool

Sometimes we need a page click can be “one key copy” function, may be useful to a called VUE-Clipboard library, know the use of the command, to achieve a copy of nature is not the next, then start to write a vueCopy, for the future development project to reduce the use of a third party library.

First let’s see how this tool works:

It can be seen that the author is also the use of the instruction, according to his idea, began to masturbate a, here directly on the code, specific ideas see notes:

clipboard: {
  bind(el, binding, { context }) {
    const _this = context
    // Use arG to inject callback function
    if (binding.arg === 'success') {
      _this.__clipboardSuccess = _this[binding.expression]
    } else if (binding.arg === 'error') {
      _this.__clipboardError = _this[binding.expression]
    } else { // The text is normally cached
      _this.__clipboardValue = binding.value
    }
    el.handler = () = > {
      if(! _this.__clipboardValue) {this.__clipboardError && this.__clipboardError('No content')
        return
      }
      if (binding.arg) { // We limit the number of times the property is executed because it is used more than once
        return
      }
      try {
        const textarea = document.createElement('textarea')
        textarea.readOnly = 'readonly' // Disable input, readonly prevents error focus on the phone from automatically evoking the keyboard
        textarea.setAttribute('style'.'position:fixed; top:-9999px; left:-9999px; ') // It is visible, but it is invisible
        textarea.value = binding.value
        document.body.appendChild(textarea)
        textarea.select()
        const result = document.execCommand('Copy')
        if (result) {
          _this.__clipboardSuccess && _this.__clipboardSuccess(binding.value) // Here you can define the data returned by the successful callback
        }
        document.body.removeChild(textarea)
      } catch (e) {
        this.__clipboardError && this.__clipboardError(e)
      }
    }
    el.addEventListener('click', el.handler)
  },
  componentUpdated(el, { arg, value }, { context }) { // Triggered when the value is updated
    const _this = context
    if(! arg) {// Do not assign values to the part of the registered callback
      _this.__clipboardValue = value
    }
  },
  unbind(el) {
    el.removeEventListener('click', el.handler)
  },
}
Copy the code

Simple use:

<div v-clipboard="'copy copy Text'">Click to copy directly to clipboard</div>
Copy the code

Use of backtone:

<template>
    <div v-clipboard="text" v-clipboard:success="success" v-clipboard:error="error">copy copy Text</div>
</template>

<script>
export default {
  data() {
    return {
      text: 123}},methods: {
    success(e) {
      console.log(e); // Replication success callback
    },
    error(e) {
      console.log(e); // Replication failed callback}}}</script>
Copy the code

Through above share three examples, I believe everyone is feeling the Vue powerful and convenient to custom orders, we can achieve more common things: such as long according to the function, or make up being throttling a instruction, etc., but here more, perhaps see here you also thought of some can use what you can do custom orders? Or do you often use custom instructions for development at work? Welcome to share the discussion.