记录el-input type=textarea引发的问题

1,071 阅读1分钟

场景在el-table中使用el-input,并在外层使用了v-if,那么此时el-input的属性autosize将失效,造成高度溢出. 原因:外层使用了v-if造成此时元素还没有创建,type=textarea无法使用autosize的方法,进行动态自适应高度.

       <template v-if="***">     
          <el-table-column prop="**" label="**" width="140" align="center">
            <template slot-scope="{row, $index}">
              <el-form-item :prop="**" :rules="**">
                <el-input type="textarea" autosize v-model="**">
                </el-input>
              </el-form-item>
            </template>
          </el-table-column>
          ****
       </template>

解决方案:

1.将v-if 换成 v-show (v-show元素已创建,通过display控制显示与隐藏)

2.在恰当的时机重新调用 autosize 的resizeTextarea()

   给 el-input 加上 ref="xxx"
   改变 autosize 后 调用 this.$refs.xxx.resizeTextarea();
   也可以再 nextTick 中调用
   this.$nextTick(() => { this.$refs.xxx.resizeTextarea(); });
   
   
   尝试过此方法,只会在列表的最后一行生效,可能是我调用的时机出现了点问题,既然是因为v-if导致autosize没有
   
   挂载相应的方法,那么使用v-show直接搞定
   

替换v-show的新问题 ---列表顺序错乱

       <div v-show="***">     
          <el-table-column prop="**" label="**" width="140" align="center">
            <template slot-scope="{row, $index}">
              <el-form-item :prop="**" :rules="**">
                <el-input type="textarea" autosize v-model="**">
                </el-input>
              </el-form-item>
            </template>
          </el-table-column>
          ****
       </div>
       ****
       会造成列表顺序并非自己想要的,暂时还没有发现问题所在,将v-show写在cloumn即可,现实就是v-show写在
       column不生效.头裂开了,v-show起作用的本质是display:none,
       而因为td的display: table-cell;权限高于display:none,所以v-show失效.呃呃呃
       看样子还得写在外层,要弄清楚为什么列表顺序错乱,还是逃不了...
       经过反复是试错,v-show不能控制el-table列的显示隐藏(可能还有其他的方法,暂时没发现),
       
       
       
       

回到起点

最后还是需要使用v-if才符合业务需求,那就回到了何时重新调用resizeTextarea()方法问题上了 尝试了监听v-if条件成立时,执行 this.nextTick(() => { this.refs.xxx.resizeTextarea(); });问题依然没有解决;

在更新组件生命周期钩子执行 this.nextTick(() => { this.refs.xxx.resizeTextarea(); });还是不行,

  watch: {
    '**.**': {
      handler(newVal, oldVal) {
      
        if (newVal === '***') {
          this.$nextTick(() => {
             this.$refs.xxx.resizeTextarea()
          })
        }
      },
      deep: true,
      immediate: true
    }
  },

想想什么情况下会有元素的介入的操作----对没错,可以自定义指令,指令可以操作元素的插入,更新执行一些操作

   <template v-if="***">     
          <el-table-column prop="**" label="**" width="140" align="center">
            <template slot-scope="{row, $index}">
              <el-form-item :prop="**" :rules="**">
                <el-input type="textarea" autosize v-model="**" v-insert>
                </el-input>
              </el-form-item>
            </template>
          </el-table-column>
          ****
   </template>
   directives: {
        insert: {
          bind(el, binding, vnode) {
            let componentInstance = vnode.componentInstance;
            componentInstance.resizeTextarea();
          },
          update(el, binding, vnode) {
            let componentInstance = vnode.componentInstance;
            componentInstance.resizeTextarea();
          },
        },
      },

自定义指令可以完美解决我的问题,不论怎么切换,高度都是自适应的,至此头发掉了一根~~~~

最后的疑问,其实指令调用的也是那个方法,为什么在监听,和更新的时候调用就不起作用呢?

欢迎各位大神指教!