A VUE project usually has a corresponding global method, through the global introduction of the way, more trouble.

The main form of code reuse and abstraction in Vue2.0 is components. However, there are cases where you still need to perform low-level operations on normal DOM elements, and custom directives are used.

  • Create a directives directory to place the custom directives
  • Create a new complugin.js to implement the corresponding global method

UFO case:

import WaterMarker from './directives/waterMarker' import Copy from './directives/copy' import Throttle from './directives/throttle' let ComPlugin = {} ComPlugin.install = function (Vue, Options) {// globalMethod or attribute vue. globalMethod = function () {} // global custom directive vue. directive('WaterMarker', {... WaterMarker }) Vue.directive('Copy', { ... Copy }) Vue.directive('Throttle', { ... Throttle}) // Add mixins Vue. Mixin ({methods: Prototype.$myMethod = function () {}} export default ComPluginCopy the code

WaterMarker. Js code

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)' / / empty the sketchpad _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)' / / empty the sketchpad _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. The value. The text) {/ / update waterMarker text toolMarker. UpdatedWaterMarker (binding. Value. Text, binding.value.textColor || '', el) } }, unbind: function () { toolMarker.cleanWaterMarker && toolMarker.cleanWaterMarker() }, } export default lkWaterMarkerCopy the code

Copy.js leverages two existing Web apis (the former is part of HTML5 and the latter is part of the HTML Editing API) :

HTMLInputElement.select()
document.execCommand()
Copy the code

The most used clipboard.js library is also based on the above API. The Async Clipboard API is here

const Copy = { bind(el, { value }) { el.$value = value el.handler = () => { if (! El. $value) {console.warn(' empty ') return} const _textareaDom = document.createElement('textarea') // Set _textareaDom to Readonly prevent iOS automatically evoke keyboard _textareaDom. Readonly = 'readonly' _textareaDom. Style. The position = 'absolute' _textareadom.style. left = '-999px' // To assign the value of the copy to the value attribute of the textarea tag _textareadom. value = el _textareaDom inserted into the document in the body. The body. The appendChild (_textareaDom) / / selected values and copy _textareaDom. Select () const result = Document. ExecCommand (' Copy ') if (result) {the console. The log (' Copy success ') / / according to project the UI design carefully} document. Body. RemoveChild (_textareaDom) } el.addEventListener('click', el.handler) }, componentUpdated(el, { value }) { el.$value = value }, unbind(el) { el.removeEventListener('click', el.handler) }, } export default CopyCopy the code

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 lkThrottleCopy the code

App. Use js

import ComPlugin from 'xxx/comPlugin.js'
Vue.use(ComPlugin)
Copy the code

Custom instruction parameter details:

The directive defines several hook functions for a function:

  • Bind: called once, when the directive is first bound to an element. You can define an initialization action that is performed once at binding time.
  • Inserted: Called when the bound element is inserted into its parent (the parent is called if it exists, not in the document).
  • Update: Called when the template to which the element is bound is updated, regardless of whether the binding value changes. By comparing the binding values before and after the update.
  • ComponentUpdated: Called when the template to which the bound element belongs completes an update cycle.
  • Unbind: Called only once, when an instruction is unbound from an element.

The instruction hook function is passed the following arguments:

  • El: The element bound by the directive that can be used to manipulate the DOM directly.
  • Binding: An object containing the following properties:
    • Name: indicates the command name, excluding the V – prefix.
    • Value: specifies the binding value of the directive. For example, v-my-directive=”1 + 1″, the binding value is 2.
    • OldValue: The previous value of the directive binding, available only in the UPDATE and componentUpdated hooks. Available regardless of whether the value changes.
    • Expression: command expression in the form of a string. For example, if v-my-directive=”1 + 1″, the expression is “1 + 1”.
    • Arg: Optional parameter passed to the instruction. For example, v-my-directive:foo, the parameter is “foo”.
    • Modifiers: An object that contains modifiers. For example, in v-my-directive.foo.bar, the modifier object is {foo: true, bar: true}.
  • Vnode: virtual node generated by Vue compilation. Go to the VNode API to learn more.
  • OldVnode: Last virtual node, available only in update and componentUpdated hooks.

Input autofocus can also be customized, or set focus=”true”, real development, always unexpected this amount.

Directive ('focus', {// When the bound element is inserted into the DOM... Inserted: function (el) {// Focus element el.focus()}})Copy the code

Other custom instructions