20210728vant中的textarea的autosize的minHeight失效问题

前提的需求:

公司做了一个设计器,我们对一些组件进行二次封装。移动端我采取了vant这个UI框架。在写textarea的时候,发现的时候,autosize中的minHeight失效的问题。

解决minHeight失效问题,只需要在需要使用自适应的时候,将传递过来的minHeight转成行数,赋值给rows就行。

我们是后端给我们传的自适应的值是行数,最小行和最大行。所以这里需要将行数改为高度。从element参考的文件:

calcTextareaHeight.js(将行数换算成高度,并且返回了minHeight,height,maxHeight。入参是$el,minRows,maxRows)

let hiddenTextarea
const HIDDEN_STYLE = `
  height:0 !important;
  visibility:hidden !important;
  overflow:hidden !important;
  position:absolute !important;
  z-index:-1000 !important;
  top:0 !important;
  right:0 !important
`

const CONTEXT_STYLE = [
  'letter-spacing',
  'line-height',
  'padding-top',
  'padding-bottom',
  'font-family',
  'font-weight',
  'font-size',
  'text-rendering',
  'text-transform',
  'width',
  'text-indent',
  'padding-left',
  'padding-right',
  'border-width',
  'box-sizing'
]

function calculateNodeStyling(targetElement1) {
  if (targetElement1) {
    const style = window.getComputedStyle(targetElement1)

    const boxSizing = style.getPropertyValue('box-sizing')

    const paddingSize = (
      parseFloat(style.getPropertyValue('padding-bottom')) +
      parseFloat(style.getPropertyValue('padding-top'))
    )

    const borderSize = (
      parseFloat(style.getPropertyValue('border-bottom-width')) +
      parseFloat(style.getPropertyValue('border-top-width'))
    )
    const contextStyle = CONTEXT_STYLE
      .map(name => `${name}:${style.getPropertyValue(name)}`)
      .join(';')
    return { contextStyle, paddingSize, borderSize, boxSizing }
  } else {
    console.log('it‘s null')
  }
}

export default function calcTextareaHeight(
  targetElement1,
  minRows = 1,
  maxRows = null
) {
  if (!hiddenTextarea) {
    hiddenTextarea = document.createElement('textarea')
    document.body.appendChild(hiddenTextarea)
  }
  let {
    paddingSize,
    borderSize,
    boxSizing,
    contextStyle
  } = calculateNodeStyling(targetElement1)

  hiddenTextarea.setAttribute('style', `${contextStyle};${HIDDEN_STYLE}`)
  hiddenTextarea.value = targetElement1.value || targetElement1.placeholder || ''

  let height = hiddenTextarea.scrollHeight
  const result = {}

  if (boxSizing === 'border-box') {
    height = height + borderSize
  } else if (boxSizing === 'content-box') {
    height = height - paddingSize
  }

  hiddenTextarea.value = ''
  let singleRowHeight = hiddenTextarea.scrollHeight - paddingSize
  if (minRows !== null) {
    let minHeight = singleRowHeight * minRows
    if (boxSizing === 'border-box') {
      minHeight = minHeight + paddingSize + borderSize
    }
    height = Math.max(minHeight, height)

    result.minHeight = `${minHeight}`
  }
  if (maxRows !== null) {
    let maxHeight = singleRowHeight * maxRows
    if (boxSizing === 'border-box') {
      maxHeight = maxHeight + paddingSize + borderSize
    }
    height = Math.min(maxHeight, height)
    result.maxHeight = `${maxHeight}`
  }
  result.height = `${height}`
  hiddenTextarea.parentNode && hiddenTextarea.parentNode.removeChild(hiddenTextarea)
  hiddenTextarea = null
  return result
}

在vue里面使用:

js:

import calcTextareaHeight from './calcTextareaHeight'

props: {
  value: {
    type: null,
    require: false
  },
  resize: String
},
mounted() {
  this.resizeTextarea()

  if (this.getEllipsis() || this.getAdaptiveValue()) { // 设置了自适应
  // 因为最小的高度不生效,所以这里设置一个rows就可以当做是最小高度了
    this.propertyAttr.rows = this.getAdaptiveValue().minRows 
    this.textareaCalcStyle = this.merge({}, this.textareaCalcStyle, { resize: this.resize })
    this.autosize = { maxHeight: this.textareaCalcStyle.maxHeight }
    console.log(this.autosize)
  } else {
    this.autosize = false
  }
},
methods: {
  resizeTextarea() {
    // 获取最小rows和最大rows,通过方法计算高度并返回。
  const minRows = this.getAdaptiveValue().minRows
  const maxRows = this.getAdaptiveValue().maxRows
  this.textareaCalcStyle = calcTextareaHeight(this.$refs.textarea.$refs.input, minRows, maxRows)
},
merge(target) {
  for (let i = 1, j = arguments.length; i < j; i++) {
    let source = arguments[i] || {}
    for (let prop in source) {
      if (source.hasOwnProperty(prop)) {
        let value = source[prop]
        if (value !== undefined) {
          target[prop] = value
        }
      }
    }
  }
  return target
 }     
}

这样就可以了!

你可能感兴趣的:(vue,vue.js,前端,vant,移动端)