Solution of invalid custom instruction on El input node

Time:2021-1-23

The purpose of this paper is to solve the problem of initialization failure of user-defined decimal instruction on El input

Problem brief

It aims to solve community Q & AThe user-defined instruction modifies the underlying DOM element, but it has no effect
Solution of invalid custom instruction on El input node
After the page first loads
Solution of invalid custom instruction on El input node
Effect to be achieved
Solution of invalid custom instruction on El input node

Initialization has no effect, butinputValid when focus is lost

Solutions

We usually want to use a filter, but considering the non common value, which is the processing of the input node value, we naturally use the hook function of the custom instructionbindTo bind events to nodes and handle formatting(XEUtilsIt’s a tool library. The link is given at the end of the chapterinput.valuevalue

Bind: it is called only once. It is called when the instruction is bound to an element for the first time. It can be initialized

Vue.directive('money', {
        //Initialization settings
        bind: function (el, binding, vnode, oldVnode) {
            el.value = XEUtils.commafy(el.value, { digits: binding.arg })
            el.onblur = () => {
                el.value = XEUtils.commafy(el.value, { digits: binding.arg })
            }
        }
    })

But he was beaten in the face immediately, and the subject reported that he was wrong

Cause of error

  1. The above code assumes that theDomIs rendering in nativeinputlabel
  2. el-inputyeselement-uiCustom components, itsDomThe structure is as follows
<div class="el-input">
    < input type = "text" autocomplete = "off" placeholder = "please input content" class = "El input"__ inner">
</div>

The above conditions can be used in the body of bind hookel.dataset.pardon = 'test'confirm. In other words,v-moneystayinputAvailable on, but onel-inputInvalid on because it is bound todivInstead ofinputElements.

DOM layout

<div id="app">
        <h1>{{ money }}</h1>
        <p>v- money:2 vue Instruction visible value: < input V-model = "money" V- money:2 ></p>
        <p>THDS (1) thousandth filter: {{money | THDS (1)}}</p>
        < El input V-model = "money" placeholder = "please input content" autosize V- money:2 ></el-input>
    </div>

crux

Render the tree, and the child node finishes rendering, traces back to the parent tree, repeats until the root, and then replaces#appNode content
bindIt is called only once when the instruction binds the node, and it can’t guarantee that the child node is OK. FortunatelyvueProvided

Inserted: called when the bound element is inserted into the parent node

In other words, in the rendering period, after the child node is compiled, the parent node is inserted, and then the parent node is compiled until the root. So we can do this, let’s gov-moneyInstruction compatibilityel-input, not justinput

Vue.directive('money', {
        inserted: function (el, binding) {
            //The instruction acts on the element input node, corresponding to the native div.el -Input (the parent of the real input node)
            if (el.tagName.toLocaleUpperCase() !== 'INPUT') {
                el = el.getElementsByTagName('input')[0]
            }
            el.value = XEUtils.commafy(el.value, { digits: binding.arg })
            el.onblur = () => {
                el.value = XEUtils.commafy(el.value, { digits: binding.arg })
            }
        }
    })

Global filter

//Filter parameters are usually associated with formatting, with values
    Vue.filter('thds', function (value, digits) {
        if (!value) return ''
        return XEUtils.commafy(value, { digits })
    })

resources

<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    <! -- import component library -- >
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/element-ui/lib/index.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/xe-utils"></script>

Source code

El input custom decimal instruction v-money

This work adoptsCC agreementReprint must indicate the author and the link of this article