<input:tabindex="tabindex"v-if="type !== 'textarea'"class="el-input__inner"v-bind="$attrs":type="showPassword ? (passwordVisible ? 'text': 'password') : type":disabled="inputDisabled":readonly="readonly":autocomplete="autoComplete || autocomplete"ref="input"@compositionstart="handleCompositionStart"@compositionupdate="handleCompositionUpdate"@compositionend="handleCompositionEnd"@input="handleInput"@focus="handleFocus"@blur="handleBlur"@change="handleChange":aria-label="label">
<el-input maxlength="5" minlength="2"></el-input>
- 通过
v-bind="$attrs"来将父元素el-input上 maxlength,minlength 等这些 input 的原生属性绑定在子元素 input 上,这样子就不用通过 prop 来进行传递配置mixins
```typescript import emitter from ‘element-ui/src/mixins/emitter’
mixins: [emitter, Migrating],
```typescript// element-ui/src/mixins/emitter/*** 广播,就是父组件向后代组件广播事件* 通过不断递归子组件,触发所需组件的对应事件* @param {*} componentName 目标组件名称* @param {*} eventName 要触发的事件名* @param {*} params 参数*/function broadcast (componentName, eventName, params) {// 遍历当前组件实例的所有子组件this.$children.forEach(child => {// 拿到子组件名称var name = child.$options.componentName// 如果当前子组件就是目标组件if (name === componentName) {// 通知子组件触发对应事件child.$emit.apply(child, [eventName].concat(params))} else {// 递归遍历深层子组件broadcast.apply(child, [componentName, eventName].concat([params]))}})}export default {methods: {// 派发,就是子组件向父组件派发事件dispatch (componentName, eventName, params) {// 获取当前组件的父组件var parent = this.$parent || this.$root// 拿到父组件名称var name = parent.$options.componentName// 通过循环的方式不断向父组件查找目标组件while (parent && (!name || name !== componentName)) {parent = parent.$parentif (parent) {name = parent.$options.componentName}}// 当循环结束,证明目标父组件已找到(如果存在),就通知父组件触发相应事件if (parent) {parent.$emit.apply(parent, [eventName].concat(params))}},broadcast (componentName, eventName, params) {// 把 this 指向调用它的组件实例身上broadcast.call(this, componentName, eventName, params)}}}
handleBlur (event) {this.focused = falsethis.$emit('blur', event)if (this.validateEvent) {this.dispatch('ElFormItem', 'el.form.blur', [this.value])}}
当 input 失去焦点时进行校验,通过 dispatch 和 broadcast 来解决深层次的父子组件通信问题
依赖注入
inject: {elForm: {default: ''},elFormItem: {default: ''}},
组件嵌套较深时使用,避免使用 this.$parent 来不断递归寻找所属组件
监听属性
在 watch 中尽量执行一些 异步或开销大的操作
watch: {// 监听 value 的变化value (val) {// 当 value 变化了需要重新改变文本域的大小// 这个属于 DOM 操作,所以放在 $nextTick() 中this.$nextTick(this.resizeTextarea)// 如果需要校验,那就要通知父组件触发 change 方法if (this.validateEvent) {this.dispatch('ElFormItem', 'el.form.change', [val])}},// 监听 type 的变化,type 为 input 或者 textareatype () {// 同样当 type 变化时,DOM 也会发生改变this.$nextTick(() => {this.setNativeInputValue()this.resizeTextarea()this.updateIconOffset()})}}
$nextTick( DOM 更新后执行回调函数以获取最新的 DOM) 使用时机
生命周期created()函数中进行的 DOM 操作一定要放在$nextTick()中,因为created()函数执行时 页面中 DOM 节点还没有渲染,拿不到 DOM 节点
- 当你的数据更新之后,需要手动操作 DOM 元素时,可以讲逻辑写在回调函数里
参考资料
