話很少說先看效果,這個效果是用在真實項目中的實際效果哈: javascript
按照慣例,先請出官方的解釋:html
指令 (Directives) 是帶有 v- 前綴的特殊特性。指令特性的值預期是單個 JavaScript 表達式 (v-for 是例外狀況,稍後咱們再討論)。指令的職責是,當表達式的值改變時,將其產生的連帶影響,響應式地做用於 DOM。vue
再按照慣例,你們 ( 僞裝 ) 看不懂,而後我來舉個栗子解釋一番。。。好,仍是不知所云,本文結束 ( Ctrl + F4
) ,下一篇。java
爲了不上述狀況出現,就不解釋了。實際上官方提供了不少內置指令,如:v-if
、v-for
、v-bind
and so on。每個指令都有本身特定的功能。node
顧名思義就是本身定義的指令啦,能夠實現咱們想要的功能。下面就實現一個 一鍵 Copy
的功能吧。express
首先簡單瞟一下指令的語法,每一個指令都有本身的生命週期,看到生命週期,確定會想到鉤子函數,沒錯,指令也提供了鉤子函數:api
bind
:指令第一次綁定到元素時調用,此鉤子只會調用一次。在這裏能夠進行一次性的初始化設置。inserted
:被綁定元素插入父節點時調用 (僅保證父節點存在,但不必定已被插入文檔中)。update
:所在組件的 VNode 更新時調用,可是可能發生在其子 VNode 更新以前。指令的值可能發生了改變,也可能沒有。componentUpdated
:指令所在組件的 VNode 及其子 VNode 所有更新後調用。unbind
:只調用一次,指令與元素解綁時調用。下面再簡單瞟一眼上述鉤子函數的參數哈:瀏覽器
el
:指令所綁定的元素,能夠用來直接操做 DOM
。binding
:一個對象,包含如下屬性:name
:指令名,不包括 v-
前綴。value
:指令的綁定值,例如:v-my-directive="1 + 1"
中,綁定值爲 2
。oldValue
:指令綁定的前一個值,僅在 update
和 componentUpdated
鉤子中可用。不管值是否改變均可用。expression
:字符串形式的指令表達式。例如 v-my-directive="1 + 1"
中,表達式爲 "1 + 1
"。arg
:傳給指令的參數,可選。例如 v-my-directive:foo
中,參數爲 "foo
"。modifiers
:一個包含修飾符的對象。例如:v-my-directive.foo.bar
中,修飾符對象爲 { foo: true, bar: true }
。vnode
:Vue
編譯生成的虛擬節點。移步 VNode API
來了解更多詳情。oldVnode
:上一個虛擬節點,僅在 update
和 componentUpdated
鉤子中可用。看起來還挺多的,不過別方,其實經常使用的就幾個。好了下面要開始表演了:app
等等,仍是再捋一下思路吧:dom
copy
:實際上瀏覽器提供了原生 api,可是隻能 copy
選中的值(就是鼠標選中的那種)。api
,選中的就是當前控件的 value
值。input
標籤input.value
api
選中 input.value
api
複製選中的值js
文件(v-copy.js)。定義一個對象。( 指令實際就是一個對象 )import { Message } from 'ant-design-vue';
const vCopy = { // 名字愛取啥取啥
/* bind 鉤子函數,第一次綁定時調用,能夠在這裏作初始化設置 el: 做用的 dom 對象 value: 傳給指令的值,也就是咱們要 copy 的值 */
bind(el, { value }) {
el.$value = value; // 用一個全局屬性來存傳進來的值,由於這個值在別的鉤子函數裏還會用到
el.handler = () => {
if (!el.$value) {
// 值爲空的時候,給出提示,我這裏的提示是用的 ant-design-vue 的提示,大家隨意
Message.warning('無複製內容');
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();
// textarea.setSelectionRange(0, textarea.value.length);
const result = document.execCommand('Copy');
if (result) {
Message.success('複製成功');
}
document.body.removeChild(textarea);
};
// 綁定點擊事件,就是所謂的一鍵 copy 啦
el.addEventListener('click', el.handler);
},
// 當傳進來的值更新的時候觸發
componentUpdated(el, { value }) {
el.$value = value;
},
// 指令與元素解綁的時候,移除事件綁定
unbind(el) {
el.removeEventListener('click', el.handler);
},
};
export default vCopy;
複製代碼
Copy
的功能就實現了,最後再說一嘴怎麼將自定義指令註冊到全局:再新建一個 js
( directives.js )文件來註冊全部的全局指令。import copy from './v-copy';
// 自定義指令
const directives = {
copy,
};
// 這種寫法能夠批量註冊指令
export default {
install(Vue) {
Object.keys(directives).forEach((key) => {
Vue.directive(key, directives[key]);
});
},
};
複製代碼
main.js
中這樣引入:import Vue from 'vue';
import Directives from './directives';
Vue.use(Directives);
複製代碼
<template>
<button v-copy="copyText">copy</button>
</template>
<script> export default { data() { return { copyText: '要 Copy 的內容', }; }, }; </script>
複製代碼
OK 所有搞完了,撒花。