index.jsx 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import './style.less'
  2. import { getStrFullLength, cutStrByFullLength } from '../_util/util'
  3. import Input from 'ant-design-vue/es/input'
  4. const TextArea = Input.TextArea
  5. export default {
  6. name: 'LimitTextArea',
  7. model: {
  8. prop: 'value',
  9. event: 'change'
  10. },
  11. props: Object.assign({}, TextArea.props, {
  12. prefixCls: {
  13. type: String,
  14. default: 'ant-textarea-limit'
  15. },
  16. // eslint-disable-next-line
  17. value: {
  18. type: String
  19. },
  20. limit: {
  21. type: Number,
  22. default: 200
  23. }
  24. }),
  25. data () {
  26. return {
  27. currentLimit: 0
  28. }
  29. },
  30. watch: {
  31. value (val) {
  32. this.calcLimitNum(val)
  33. }
  34. },
  35. created () {
  36. this.calcLimitNum(this.value)
  37. },
  38. methods: {
  39. handleChange (e) {
  40. const value = e.target.value
  41. const len = getStrFullLength(value)
  42. if (len <= this.limit) {
  43. this.currentLimit = len
  44. this.$emit('change', value)
  45. return
  46. } else {
  47. const str = cutStrByFullLength(value, this.limit)
  48. this.currentLimit = getStrFullLength(str)
  49. this.$emit('change', str)
  50. }
  51. console.error('limit out! currentLimit:', this.currentLimit)
  52. },
  53. calcLimitNum (val) {
  54. const len = getStrFullLength(val)
  55. this.currentLimit = len
  56. }
  57. },
  58. render () {
  59. const { prefixCls, ...props } = this.$props
  60. return (
  61. <div class={this.prefixCls}>
  62. <TextArea {...{ props }} value={this.value} onChange={this.handleChange}>
  63. </TextArea>
  64. <span class="limit">{this.currentLimit}/{this.limit}</span>
  65. </div>
  66. )
  67. }
  68. }