一个vue 工程,通常都会有对应的全局方法,通过全局引入的方式,更省事。
引用官方:在 Vue2.0 中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。
- 新建一个directives 来放置自定义指令
- 新建一个comPlugin.js 来实现对应全局方法的实现
案例:
import WaterMarker from './directives/waterMarker'
import Copy from './directives/copy'
import Throttle from './directives/throttle'
let ComPlugin = {}
ComPlugin.install = function (Vue, options) {
// 全局方法或属性
Vue.globalMethod = function () {}
// 全局自定义指令
Vue.directive('WaterMarker', { ...WaterMarker })
Vue.directive('Copy', { ...Copy })
Vue.directive('Throttle', { ...Throttle })
// 全局注入mixins
Vue.mixin({
methods: {
aa() {},
},
})
// 实例方法
Vue.prototype.$myMethod = function () {}
}
export default ComPlugin
waterMarker.js 代码
let toolMarker = (function () {
let _can = document.createElement('canvas')
let _div = document.createElement('div')
_div.id = 'waterMarker'
document.body.appendChild(_can)
_can.width = 300
_can.height = 360
_can.style.display = 'none'
let _cans = _can.getContext('2d')
_cans.font = '26px Microsoft Yahei'
_cans.rotate((-20 * Math.PI) / 180)
function drawWaterMarker(str, textColor) {
_cans.fillStyle = textColor || 'rgba(180, 180, 180, 0.2)'
// 清空画板
_cans.clearRect(0, 0, _can.width, _can.height)
_cans.fillText(str, _can.width / 10, _can.height / 2)
_div.style = `
pointer-events: none;
top: 70px;
left: 0px;
position: fixed;
z-index: 998;
width: 100%;
height: 100%;
background-image: url(${_can.toDataURL('image/png')})
`
document.body.appendChild(_div)
}
function updatedWaterMarker(textVal, textColor) {
if (_cans && _div) {
_cans.fillStyle = textColor || 'rgba(180, 180, 180, 0.2)'
// 清空画板
_cans.clearRect(0, 0, _can.width, _can.height)
_cans.fillText(textVal, _can.width / 10, _can.height / 6)
_div.style.backgroundImage = `url(${_can.toDataURL('image/png')})`
}
}
function cleanWaterMarker() {
_div && _div.parentNode.removeChild(_div)
_can && _can.parentNode.removeChild(_can)
}
return {
drawWaterMarker,
updatedWaterMarker,
cleanWaterMarker,
}
})()
const lkWaterMarker = {
bind: function (el, { value }) {
toolMarker.drawWaterMarker(value.text, value.textColor || '', el)
},
update: function (el, binding) {
let { text } = binding.oldValue
if (binding.oldValue && text && text !== binding.value.text) {
// 更新waterMarker 文字
toolMarker.updatedWaterMarker(binding.value.text, binding.value.textColor || '', el)
}
},
unbind: function () {
toolMarker.cleanWaterMarker && toolMarker.cleanWaterMarker()
},
}
export default lkWaterMarker
copy.js
const Copy = {
bind(el, { value }) {
el.$value = value
el.handler = () => {
if (!el.$value) {
console.warn('内容为空')
return
}
const _textareaDom = document.createElement('textarea')
// 将该 _textareaDom 设为 readonly 防止 iOS 下自动唤起键盘
_textareaDom.readOnly = 'readonly'
_textareaDom.style.position = 'absolute'
_textareaDom.style.left = '-999px'
// 将要 copy 的值赋给 textarea 标签的 value 属性
_textareaDom.value = el.$value
// 将 _textareaDom 插入到 body 中
document.body.appendChild(_textareaDom)
// 选中值并复制
_textareaDom.select()
const result = document.execCommand('Copy')
if (result) {
console.log('复制成功') // 可根据项目UI仔细设计
}
document.body.removeChild(_textareaDom)
}
el.addEventListener('click', el.handler)
},
componentUpdated(el, { value }) {
el.$value = value
},
unbind(el) {
el.removeEventListener('click', el.handler)
},
}
export default Copy
throttle.js
const lkThrottle = {
inserted(el, binding) {
let _inpParams = binding.value
if (!el) {
return false
}
el.time = 1500
if (Object.prototype.toString.call(_inpParams) === '[object Function]') {
el.callback = _inpParams
} else {
const { fn, _time } = binding.value
el.callback = fn
el.time = _time
}
el.addEventListener('click', () => {
const _nowTime = new Date().getTime()
if (!el.preTime || _nowTime - el.preTime > el.time) {
el.preTime = _nowTime
el.callback && el.callback(el)
}
})
},
unbind() {},
}
export default lkThrottle
app.js 处使用
import ComPlugin from 'xxx/comPlugin.js'
Vue.use(ComPlugin)
自定义指令参数详解:
指令定义函数的几个钩子函数:
- bind: 只调用一次,指令第一次绑定到元素时调用,可以定义一个在绑定时执行一次的初始化动作。
- inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。
- update: 被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值。
- componentUpdated: 被绑定元素所在模板完成一次更新周期时调用。
- unbind: 只调用一次, 指令与元素解绑时调用。
指令钩子函数会被传入以下参数:
- el:指令所绑定的元素,可以用来直接操作 DOM。
- binding:一个对象,包含以下 property:
- 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 钩子中可用。
其他自定义指令
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!