使用vue指令实现复制代码

自定义一个复制code指令

看掘金刷到Vue.directive,想想到现在自己也没写过指令,于是就想写一个指令试试。正考虑写什么好呢,瞅到了复制代码,不禁感叹:哥真是机智啊。废话不多说,撸起来!

src的目录下有关文件的路径:

├─ main.js
├─ libs
│  ├─  copy.js
│  └─  directives.js
└─ pages
   └─ Index.vue

copy.js,是指令的具体内容

const vCopy = {
  bind(el, binding, vNode) {
    function clickHandler(e) {
      if(el !== e.target) {
        return false;
      }
      let code = el.previousElementSibling.textContent
      // let code = el.previousSibling.textContent
      if(!code) {
        return false
      }

      const textarea = document.createElement('textarea')
      textarea.readOnly = 'readonly'
      textarea.style.position = 'absolute'
      textarea.style.left = '-9999px'
      textarea.value = code
      document.body.appendChild(textarea)
      textarea.select()
      const result = document.execCommand('Copy')
      if(result) {
        console.log('复制成功'); // 应该窗口提示复制成功
      }
      document.body.removeChild(textarea)
    }
    el.__vueClickOutside__ = clickHandler;
    document.addEventListener('click', clickHandler)
  },
  componentUpdated(el, {value}) {},
  unbind(el, binding) {
    document.removeEventListener('click', el.__vueClickOutside__)
    delete el.__vueClickOutside__

  }
}

export default vCopy

main.js,没有其他指令的话,使用方式一就好,只需要使用Vue.directive。如果多个指令,方式二是个不错的选择

/**
** 方式一
**/

import vCopy from './libs/copy'
Vue.directive('copy', vCopy)

/**
** 方式二
**/
import Directives from './libs/directives'
Vue.use(Directives)

directives.js,把指令汇总

import copy from './copy';

const directives = {
  copy
}

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

Index.vue,使用指令

<template>
  <div class="code">
    <pre class="code_pre">
      <code>{{code}}</code>
      <span v-copy class="copy">复制代码</span>
    </pre>
  </div>
</template>

<script>
export default {
  data() {
    return {
      code: ''
    }
  },
  created() {
    this.code = `\nlet a = 1;\nconsole.log(a++);\nfunction a() {
  var brother2 = document.getElementById("test").previousElementSibling;
}`
  },
  methods: {}
}
</script>

<style scoped>
  .code {
    width: 100%;
    min-height: 50px;
    position: relative;
    word-wrap: break-word;
    margin: 1.813rem 0;
  }
  .code_pre {
    text-align: left;
    color: #CDC;
    background-color: rgba(0, 0, 0, 0.55);
    overflow-x: auto;
    padding: 0 10px;
  }
    .copy {
      width: 70px;
      position: absolute;
      top: 12px;
      right: 0;
      font-size: 12px;
      line-height: 1;
      cursor: pointer;
      color: hsla(0, 60%, 54.9%, .9);
      transition: color .1s;
    }
</style>

写完之后想着要不要做成组件,毕竟对布局的要求比较高,转念一想,这基本算是个组件了,就到此为止吧


资料

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值