Editor.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. <template>
  2. <div>
  3. <codemirror v-model="content" :options="editorOptions" @input="handletextContentChange" class="content"></codemirror>
  4. <div slot="footer" class="dialog-footer">
  5. <div class="left">
  6. <el-button type="primary" @click="formateXml(content)">格式化</el-button>
  7. </div>
  8. <div class="right">
  9. <el-button type="primary" @click="determine">确定修改</el-button>
  10. <el-button @click="cancel">取 消</el-button>
  11. </div>
  12. </div>
  13. </div>
  14. </template>
  15. <script>
  16. //xml编辑器
  17. import { codemirror } from 'vue-codemirror'
  18. import 'codemirror/lib/codemirror.css'
  19. import 'codemirror/mode/xml/xml.js'
  20. import 'codemirror/theme/ssms.css' // 根据需要选择主题
  21. import 'codemirror/keymap/sublime'
  22. import "codemirror/addon/hint/xml-hint.js";
  23. export default {
  24. name: 'XmlEditor',
  25. components: {
  26. codemirror,
  27. },
  28. props:[ 'textContent','closeEditor','dataType'],
  29. data() {
  30. return {
  31. // 初始的 text 内容
  32. content: this.textContent,
  33. // 绑定的数据
  34. bindContentData:this.textContent,
  35. editorOptions: null,
  36. }
  37. },
  38. created(){
  39. if(this.dataType==='XML'){
  40. this.editorOptions={
  41. mode: 'xml',
  42. theme: 'ssms', // 根据需要选择主题
  43. // 缩进格式
  44. tabSize: 2,
  45. autocorrect: true, // 自动更正
  46. spellcheck: true, // 拼写检查
  47. lint: true, // 检查格式
  48. lineNumbers: true, //是否显示行数
  49. lineWrapping: true, //是否自动换行
  50. styleActiveLine: true, //line选择是是否高亮
  51. keyMap: 'sublime', // sublime编辑器效果
  52. matchBrackets: true, //括号匹配
  53. autoCloseBrackets: true, // 在键入时将自动关闭括号和引号
  54. matchTags: { bothTags: true }, // 将突出显示光标周围的标签
  55. autoFormatOnLoad: true
  56. }
  57. this.formateXml(this.content)
  58. }
  59. },
  60. methods:{
  61. handletextContentChange(textContent) {
  62. // 在这里处理 XML 内容的变化
  63. // console.log(textContent)
  64. },
  65. // xml格式化
  66. formateXml(xmlStr){
  67. var that = this;
  68. var text = xmlStr;
  69. //使用replace去空格
  70. text = '\n' + text.replace(/(<\w+)(\s.*?>)/g,function($0, name, props){
  71. return name + ' ' + props.replace(/\s+(\w+=)/g," $1");
  72. }).replace(/>\s*?</g,">\n<");
  73. //处理注释
  74. text = text.replace(/\n/g,'\r').replace(/<!--(.+?)-->/g,function($0, text){
  75. var ret = '<!--' + escape(text) + '-->';
  76. return ret;
  77. }).replace(/\r/g,'\n');
  78. //调整格式 以压栈方式递归调整缩进
  79. var rgx = /\n(<(([^\?]).+?)(?:\s|\s*?>|\s*?(\/)>)(?:.*?(?:(?:(\/)>)|(?:<(\/)\2>)))?)/mg;
  80. var nodeStack = [];
  81. var output = text.replace(rgx,function($0,all,name,isBegin,isCloseFull1,isCloseFull2 ,isFull1,isFull2){
  82. var isClosed = (isCloseFull1 == '/') || (isCloseFull2 == '/' ) || (isFull1 == '/') || (isFull2 == '/');
  83. var prefix = '';
  84. if(isBegin == '!'){//!开头
  85. prefix = that.setPrefix(nodeStack.length);
  86. }else {
  87. if(isBegin != '/'){///开头
  88. prefix = that.setPrefix(nodeStack.length);
  89. if(!isClosed){//非关闭标签
  90. nodeStack.push(name);
  91. }
  92. }else{
  93. nodeStack.pop();//弹栈
  94. prefix = that.setPrefix(nodeStack.length);
  95. }
  96. }
  97. var ret = '\n' + prefix + all;
  98. return ret;
  99. });
  100. var prefixSpace = -1;
  101. var outputText = output.substring(1);
  102. //还原注释内容
  103. outputText = outputText.replace(/\n/g,'\r').replace(/(\s*)<!--(.+?)-->/g,function($0, prefix, text){
  104. if(prefix.charAt(0) == '\r')
  105. prefix = prefix.substring(1);
  106. text = unescape(text).replace(/\r/g,'\n');
  107. var ret = '\n' + prefix + '<!--' + text.replace(/^\s*/mg, prefix ) + '-->';
  108. return ret;
  109. });
  110. outputText= outputText.replace(/\s+$/g,'').replace(/\r/g,'\r\n');
  111. this.content=outputText
  112. // return outputText;
  113. },
  114. //计算头函数 用来缩进
  115. setPrefix(prefixIndex) {
  116. var result = '';
  117. var span = ' ';//缩进长度
  118. var output = [];
  119. for(var i = 0 ; i < prefixIndex; ++i){
  120. output.push(span);
  121. }
  122. result = output.join('');
  123. return result;
  124. },
  125. determine(){
  126. this.closeEditor(this.content)
  127. },
  128. cancel(){
  129. this.closeEditor('no')
  130. }
  131. }
  132. }
  133. </script>
  134. <style scoped>
  135. ::v-deep .CodeMirror-code{
  136. font-size: 18px;
  137. }
  138. .dialog-footer{
  139. margin-top: 20px;
  140. display: flex;
  141. justify-content: space-around;
  142. }
  143. </style>