UNPKG

vxe-table

Version:

一个基于 vue 的 PC 端表格组件,支持增删改查、虚拟滚动、懒加载、快捷菜单、数据校验、树形结构、打印导出、表单渲染、数据分页、虚拟列表、模态窗口、自定义模板、渲染器、贼灵活的配置项、扩展接口等...

164 lines (161 loc) 5.11 kB
import XEUtils from 'xe-utils/ctor' import GlobalConfig from '../../conf' import vSize from '../../mixins/size' import { UtilTools } from '../../tools' let autoTxtElem export default { name: 'VxeTextarea', mixins: [vSize], props: { value: [String, Number], name: String, readonly: Boolean, disabled: Boolean, placeholder: String, maxlength: [String, Number], rows: { type: [String, Number], default: 2 }, showWordCount: Boolean, autosize: [Boolean, Object], form: String, resize: { type: String, default: () => GlobalConfig.textarea.resize }, size: { type: String, default: () => GlobalConfig.textarea.size || GlobalConfig.size } }, computed: { inputCount () { return XEUtils.getSize(this.value) }, isCountError () { return this.maxlength && this.inputCount > XEUtils.toNumber(this.maxlength) }, defaultEvents () { const evnts = {} XEUtils.each(this.$listeners, (cb, name) => { if (['change'].indexOf(name) === -1) { evnts[name] = this.triggerEvent } }) evnts.input = this.inputEvent return evnts }, sizeOpts () { return Object.assign({ minRows: 1, maxRows: 10 }, GlobalConfig.textarea.autosize, this.autosize) } }, watch: { value () { this.updateAutoTxt() } }, mounted () { if (this.value) { this.updateAutoTxt() this.handleResize() } }, render (h) { const { defaultEvents, value, vSize, name, form, resize, placeholder, readonly, disabled, maxlength, autosize, showWordCount } = this const attrs = { name, form, placeholder, maxlength, readonly, disabled } if (placeholder) { attrs.placeholder = UtilTools.getFuncText(placeholder) } return h('div', { class: ['vxe-textarea', { [`size--${vSize}`]: vSize, 'is--autosize': autosize, 'is--disabled': disabled }] }, [ h('textarea', { ref: 'textarea', class: 'vxe-textarea--inner', domProps: { value }, attrs, style: resize ? { resize } : null, on: defaultEvents }), showWordCount ? h('span', { class: ['vxe-textarea--count', { 'is--error': this.isCountError }] }, `${this.inputCount}${maxlength ? `/${maxlength}` : ''}`) : null ]) }, methods: { focus () { this.$refs.textarea.focus() return this.$nextTick() }, blur () { this.$refs.textarea.blur() return this.$nextTick() }, triggerEvent (evnt) { const { value } = this this.$emit(evnt.type, { value, $event: evnt }) }, emitUpdate (value, evnt) { if (this.value !== value) { this.$emit('input', value) this.$emit('change', { value, $event: evnt }) } }, inputEvent (evnt) { this.emitUpdate(evnt.target.value, evnt) this.handleResize() }, updateAutoTxt () { const { $refs, value, size, autosize } = this if (autosize) { if (!autoTxtElem) { autoTxtElem = document.createElement('div') } if (!autoTxtElem.parentNode) { document.body.appendChild(autoTxtElem) } const textElem = $refs.textarea const textStyle = getComputedStyle(textElem) autoTxtElem.className = ['vxe-textarea--autosize', size ? `size--${size}` : ''].join(' ') autoTxtElem.style.width = `${textElem.clientWidth}px` autoTxtElem.style.padding = textStyle.padding autoTxtElem.innerHTML = ('' + (value || ' ')).replace(/\n$/, '\n ') } }, handleResize () { if (this.autosize) { this.$nextTick(() => { const { $refs, sizeOpts } = this const { minRows, maxRows } = sizeOpts const textElem = $refs.textarea const sizeHeight = autoTxtElem.clientHeight const textStyle = getComputedStyle(textElem) const lineHeight = XEUtils.toNumber(textStyle.lineHeight) const paddingTop = XEUtils.toNumber(textStyle.paddingTop) const paddingBottom = XEUtils.toNumber(textStyle.paddingBottom) const borderTopWidth = XEUtils.toNumber(textStyle.borderTopWidth) const borderBottomWidth = XEUtils.toNumber(textStyle.borderBottomWidth) const intervalHeight = paddingTop + paddingBottom + borderTopWidth + borderBottomWidth const rowNum = (sizeHeight - intervalHeight) / lineHeight const textRows = rowNum && /[0-9]/.test(rowNum) ? rowNum : Math.floor(rowNum) + 1 let vaildRows = textRows if (textRows < minRows) { vaildRows = minRows } else if (textRows > maxRows) { vaildRows = maxRows } textElem.style.height = `${(vaildRows * lineHeight) + intervalHeight}px` }) } } } }