vue实用指令

先批量注册组件指令,新建directives/index.js文件

import copy from './copy'

const directives = {
    copy
}

const install = function (Vue) {
    Object.keys(directives).forEach((key) => {
        Vue.directive(key, directives[key])
    })
}

export default install

在main.js中导入文件

import Vue from 'vue'
import Directives from '@/directives/index'
Vue.use(Directives)

一、点击复制文本指令

新建directives/copy.js文件

/*
 * 实现思路
 * 动态创建 textarea 标签,并设置 readOnly 属性及移出可视区域
 * 将要复制的值赋给 textarea 标签的 value 属性,并插入到 body
 * 选中值 textarea 并复制
 * 将 body 中插入的 textarea 移除
 * 在第一次调用时绑定事件,在解绑时移除事件
 */
const copy = {
    bind(el, binding) {
        const value = binding.value
        el.$value = value
        const abc = () => {
            if (!el.$value) {
                // 值为空时
                console.log('无复制内容!')
                return
            }
            // 动态创建textarea标签
            const textarea = document.createElement('textarea')
            // 将该textarea设为readonly防止ios下自动唤起键盘,同时将textarea移出可视区域
            textarea.readOnly = 'readonly'
            textarea.style.position = 'absolute'
            textarea.style.left = '-9999px'
            // 将要copy的值赋值给textarea标签的value属性
            textarea.value = el.$value
            // 将textarea插入到body中
            document.body.appendChild(textarea)
            // 选中值
            textarea.select()
            // 将选中的值复制并赋值给result
            const result = document.execCommand('Copy')
            if (result) {
                console.log('复制成功!')
            }
            document.body.removeChild(textarea)
        }
        // 绑定点击事件
        el.addEventListener('click', abc)
    },
    // 当传进来的值更新的时候触发
    componentUpdated(el, { value }) {
        el.$value = value
    },
    // 指令与元素解绑的时候,移除事件绑定
    unbind(el) {
        el.removeEventListener('click', el.handler)
    }
}

export default copy

使用方法,点击p标签就可以实现复制

<template>
  <div>
      <p v-copy="copyText">复制</p>
  </div>
</template>

<script>
export default {
  name: 'Test',
  data() {
    return {
      copyText: 'a copy directives'
    }
  },
  methods: {}
}
</script>

<style lang="scss" scoped>
</style>

 二、拖拽指令

新建directives/draggable.js文件

// clientX    以浏览器左上顶角为原点,定位 x 轴坐标
// clientY    以浏览器左上顶角为原点,定位y轴坐标
// offsetX    以当前事件的目标对象左上角为原点,定位x轴坐标
// offsetY    以当前事件的目标对象左上角为原点,定位y轴坐标
// pageX    以Document 对象(即文本窗口)左上角为原点,定位x轴坐标
// pageY    以Document 对象(即文本窗口)左上角为原点,定位y轴坐标
// screenX    计算机屏幕左上角为原点,定位x轴坐标
// screenY    计算机屏幕左上角为原点,定位y轴坐标
// layerX    最近的绝对定位的父元素(如果没有,则为Document对象)左上角为原点,定位x轴坐标
// layerY    最近的绝对定位的父元素(如果没有,则为Document对象)左上角为原点,定位y轴坐标
const draggable = {
    inserted: function (el) {
        el.style.position = 'absolute'
        el.style.cursor = 'move'
        el.onmousedown = function (e) {
            let disx = e.pageX - el.offsetLeft
            let disy = e.pageY - el.offsetTop
            document.onmousemove = function (e) {
                let x = e.pageX - disx
                let y = e.pageY - disy
                let maxX = document.body.clientWidth - parseInt(window.getComputedStyle(el).width)
                let maxY = document.body.clientHeight - parseInt(window.getComputedStyle(el).height)
                if (x < 0) {
                    x = 0
                } else if (x > maxX) {
                    x = maxX
                }

                if (y < 0) {
                    y = 0
                } else if (y > maxY) {
                    y = maxY
                }

                el.style.left = x + 'px'
                el.style.top = y + 'px'
            }
            document.onmouseup = function () {
                document.onmousemove = document.onmouseup = null
            }
        }
    }
}
export default draggable

使用方法

<template>
  <div class="container">
      <div class="draggable_box" v-draggable></div>
  </div>
</template>

<script>
export default {
  data() {
    return {
    }
  },
  methods: {}
}
</script>

<style lang="scss" scoped>
.container {
   height: 100vh;
   width: 100vw;
   position: relative;
   .draggable_box {
      height: 100px;
      width: 100px;
      border-radius: 50%;
      border: 1px solid black;
   }
}
</style>

 二、防抖指令

const debounce = { // 防抖指令
    inserted: function (el, binding) {
        let timer
        el.addEventListener('click', () => {
            if (timer) {
                clearTimeout(timer)
            }
            timer = setTimeout(() => {
                binding.value()
            }, 500)
        })
    }
}

export default debounce

使用方法

<template>
  <div class="container">
      <div v-debounce="send"></div>
  </div>
</template>

<script>
export default {
  data() {
    return {
    }
  },
  methods: {
    send() {
       console.log('连续点击')
    }
  }
}
</script>

<style lang="scss" scoped>
</style>

 

posted @ 2020-12-16 14:09  SLfish  阅读(104)  评论(0编辑  收藏  举报