Zzhigang.liudpate
0ef9b9a8创建于 2018年7月6日历史提交
<template>
  <div class="paste-editor-wrapper">
    <textarea ref="codemirror" class="textarea-el"></textarea>
  </div>
</template>
<script>
import CodeMirror from 'codemirror'
import 'codemirror/lib/codemirror.css'
import { forEach } from '@/libs/tools'
import createPlaceholder from './plugins/placeholder'
export default {
  name: 'PasteEditor',
  props: {
    value: Array,
    pasteData: {
      type: String,
      default: ''
    },
    placeholder: {
      type: String,
      default: '从网页或其他应用软件复制表格数据,粘贴到这里 。默认第一行是表头,使用回车键添加新行,使用Tab键区分列。'
    }
  },
  data () {
    return {
      pasteDataArr: [],
      rowArrLength: 0,
      editor: null
    }
  },
  watch: {
    pasteData (val) {
      if (val === '') {
        this.editor.setValue('')
      }
    }
  },
  computed: {
    rowNum () {
      return this.pasteDataArr.length
    },
    colNum () {
      return this.pasteDataArr[0] ? this.pasteDataArr[0].length : 0
    }
  },
  methods: {
    handleKeyup (e) {
      this.handleAreaData()
    },
    /**
     * @description 处理粘贴操作
     */
    handleContentChanged (content) {
      let pasteData = content.trim()
      this.$emit('on-content-change', pasteData)
      let rows = pasteData.split((/[\n\u0085\u2028\u2029]|\r\n?/g)).map(row => {
        return row.split('\t')
      })
      if (content === '') rows = []
      this.pasteDataArr = rows
      this.clearLineClass()
      this.checkColNumInEveryRow()
      this.$emit('input', this.pasteDataArr)
    },
    /**
     * @description 检查除第一行的每一行列数是否与第一行相同
     */
    checkColNumInEveryRow () {
      let i = 0
      const len = this.rowNum
      if (len === 0) return
      while (++i < len) {
        let item = this.pasteDataArr[i]
        if (item.length !== this.colNum && (!(i === len - 1 && item.length === 1 && item[0] === '') || i !== len - 1)) {
          this.markIncorrectRow(i)
          this.$emit('on-error', i)
          return false
        }
      }
      this.$emit('on-success', this.pasteDataArr)
      return true
    },
    /**
     * @description 标记不符合格式的一行
     */
    markIncorrectRow (index) {
      this.editor.addLineClass(index, 'text', 'incorrect-row')
    },
    /**
     * @description 标记不符合格式的一行
     */
    clearLineClass () {
      forEach(this.pasteDataArr, (item, index) => {
        this.editor.removeLineClass(index, 'text', 'incorrect-row')
      })
    }
  },
  mounted () {
    createPlaceholder(CodeMirror)
    this.editor = CodeMirror.fromTextArea(this.$refs.codemirror, {
      lineNumbers: true,
      tabSize: 1,
      lineWrapping: true,
      placeholder: this.placeholder
    })
    this.editor.on('change', (editor) => {
      this.handleContentChanged(editor.getValue())
    })
    this.editor.addLineClass(0, 'text', 'first-row')
  }
}
</script>
<style lang="less">
@import './paste-editor.less';
</style>