vue-自定義directive實現v-copy指令

這是我參與更文挑戰的第2天,活動詳情查看: 更文挑戰vue

注:如下是我的理解、若有不對還望指正!大概的效果node

需求:

  • 項目多個頁面須要使用、點擊按鈕默認選中文本複製、用戶只需按ctrl + v 粘貼

考慮到技術棧是vue、並且vue也給咱們提供了插件指令的形式、很簡單的上手就能寫出一個v-copy指令、因此開幹吧express

插件文檔學習

文檔地址api

//template
<button v-copy:a="text">指令測試</button>

//data
data(){
    return {
        text:'複製的內容'
    }
}

//directive
Vue.directive('copys',{
    //被綁定元素插入父節點時調用 (僅保證父節點存在,但不必定已被插入文檔中)
    inserted (el) {
        // console.log('父節點dom',el)
    },
    //只調用一次,指令第一次綁定到元素時調用。在這裏能夠進行一次性的初始化設置。
    bind(el,binding){
        console.log('dom',el)
        console.log(binding)
        // binding:{
        // arg: "a" 傳給指令的參數 v-copy:a
        // def: {inserted: ƒ, bind: ƒ}
        // expression: "day" 字符串形式的指令表達式
        // modifiers: {} 修飾符的對象
        // name: "copys" 指令名
        // rawName: "v-copys:a" //指令總體
        // value:"複製的內容" //指令的綁定值
        // }
    },
    //在組件的 VNode 更新時調用
    update(el,binding,vnode,oldVnode){
    },
    //指令所在組件的 VNode 及其子 VNode 所有更新後調用
    componentUpdated(el,binding,vnode,oldVnode){
    },
    // 只調用一次,指令與元素解綁時調用
    unbind(el,binding,vnode,oldVnode,status){
        console.log(arguments)
    }
})
複製代碼

實戰v-copy

  • 建立copy.js
export default { 
    bind(el, { value }) { 
        el.$value = value; 
        el.handler = (e) => {
            //阻止冒泡
            e.stopPropagation();
            //建立提示元素
            let addelement = (text,color) =>{
                //獲取鼠標位置
                let scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
                let scrollY = document.documentElement.scrollTop || document.body.scrollTop;
                let x = e.pageX || e.clientX + scrollX;
                let y = e.pageY || e.clientY + scrollY;
                const $mes  = document.createElement('span');
                $mes.setAttribute('class','Copyspan');
                $mes.style = `position:fixed;left:${ x + 6 }px;top:${ y - 14}px;z-index:9999;font-size:12px; color:#343435; animation: Copyspan 800ms ease-in-out;color:${color}`;
                $mes.innerText = text;
                document.body.appendChild($mes);
                //500ms後移除
                setTimeout(()=>{
                    document.body.removeChild($mes);
                }, 500);
            }
            if (!el.$value) {
                addelement('複製成功','#f56c6c')
                return;
            }
            //建立copy元素textarea
            const $textarea = document.createElement('textarea');
            $textarea.readOnly = 'readonly';
            $textarea.style = {
                position:'absolute',
                left:'-9999px'
            }
            //賦值copy內容
            $textarea.value = el.$value;
            document.body.appendChild($textarea);
            $textarea.select();
            const result = document.execCommand('Copy');
            if (result) {
                addelement('複製成功','#67c23a')
            }
            document.body.removeChild($textarea);
        };
        el.addEventListener('click', el.handler);
    },
    //監聽vnode變化後從新獲取value
    componentUpdated(el, { value }) {
      el.$value = value;
    },
    //移除事件
    unbind(el) {
      el.removeEventListener('click', el.handler);
    },
};


複製代碼
  • main.js 全局注入
import copy from '@/directive/copy.js'
Vue.directive('copy',copy)
複製代碼

使用

<div v-copy="text">  複製的內容 </div>
複製代碼

總結

總體寫下來不難、在vue的鉤子作本身想作的邏輯操做、對原生js要求高一些markdown

相關文章
相關標籤/搜索