Vue编写一个一键 Copy的功能(包括自定义指令和插件的方式)
2019-09-26 本文已影响0人
Hellolad
除了核心功能默认内置的指令 (
v-model
和v-show
),Vue 也允许注册自定义指令。
1. 三个重要的钩子函数:
-
bind
:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。 -
componentUpdated
:指令所在组件的 VNode 及其子 VNode 全部更新后调用。 -
unbind
:只调用一次,指令与元素解绑时调用。
2. 钩子函数的重要参数(只列出比较重要的):
-
el
:指令所绑定的元素,可以用来直接操作 DOM 。 -
binding
:一个对象,包含以下属性:-
value
:指令的绑定值,例如:v-my-directive="1 + 1"
中,绑定值为2
。 -
arg
:传给指令的参数,可选。例如v-my-directive:foo
中,参数为"foo"
。
-
3. 创建一个文件copy.js
export default {
bind: function (el, binding, vnode, oldVnode) {
el.$value = ""
el.handle = function() {
const fakeElement = document.createElement('textarea')
fakeElement.readOnly = 'readonly'
fakeElement.style.position = 'absolute'
fakeElement.style.left = '-999px'
fakeElement.value = el.$value
document.body.appendChild(fakeElement)
fakeElement.select()
const result = document.execCommand('copy')
if (result) {
if (binding.arg === 'success' && typeof binding.value === 'function') {
binding.value()
}
} else {
if (binding.arg === 'fail' && typeof binding.value === 'function') {
binding.value()
}
}
document.body.removeChild(fakeElement)
}
el.addEventListener('click', el.handle)
},
componentUpdated: function (el, binding, vnode, oldVnode) {
if (typeof binding.value !== 'function') {
el.$value = binding.value
}
},
unbind: function (el, binding, vnode, oldVnode) {
el.removeEventListener('click', el.handle)
}
}
使用方法:
<el-input size="small" v-model="inputVale" placeholder="请输入内容"></el-input>
<el-button
size="small"
type="primary"
v-copy="inputVale"
v-copy:success="handleSuccess"
v-copy:fail="handleFail"
>复制内容</el-button>
import VCopy from '@/directives/copy'
export default {
name: "v-copy",
data() {
return {
inputVale: ""
};
},
methods: {
handleSuccess() {
console.log("handleSuccess 复制成功");
this.$message.success('复制成功')
},
handleFail() {
console.log("handleFail 复制失败")
this.$message.error('复制失败')
}
},
directives: {
copy: VCopy
}
};
4. 也可以使用插件的方式:
const CopyPlugin = {}
CopyPlugin.install = function (Vue, options) {
Vue.directive('copy', {
bind: function (el, binding, vnode, oldVnode) {
el.$value = ""
el.handle = function() {
const fakeElement = document.createElement('textarea')
fakeElement.readOnly = 'readonly'
fakeElement.style.position = 'absolute'
fakeElement.style.left = '-999px'
fakeElement.value = el.$value
document.body.appendChild(fakeElement)
fakeElement.select()
const result = document.execCommand('copy')
if (result) {
if (binding.arg === 'success' && typeof binding.value === 'function') {
binding.value()
}
} else {
if (binding.arg === 'fail' && typeof binding.value === 'function') {
binding.value()
}
}
document.body.removeChild(fakeElement)
}
el.addEventListener('click', el.handle)
},
componentUpdated: function (el, binding, vnode, oldVnode) {
if (typeof binding.value !== 'function') {
el.$value = binding.value
}
},
unbind: function (el, binding, vnode, oldVnode) {
el.removeEventListener('click', el.handle)
}
})
Vue.prototype.$copyfunc = function(value, callback) {
const fakeElement = document.createElement('textarea')
fakeElement.readOnly = 'redonly'
fakeElement.style.position = 'absolute'
fakeElement.style.left = '-9999px'
fakeElement.value = value
document.body.appendChild(fakeElement)
fakeElement.select()
const result = document.execCommand('copy')
document.body.removeChild(fakeElement)
if (result) {
callback('success')
} else {
callback('fail')
}
}
}
export default CopyPlugin
使用方法:
<el-input size="small" v-model="inputVale" placeholder="请输入内容"></el-input>
<el-button
size="small"
type="primary"
@click="handleCopy"
>复制内容</el-button>
handleCopy() {
this.$copyfunc(this.inputVale, (str) => {
if (str === 'success') {
this.$message.success('复制成功')
} else {
this.$message.error('复制失败')
}
})
}