Vue decompresses the compressed package online and edits the code online to save

web code editing

The effect is as follows:
online editing

1. Unzip

Online decompression requires jszip , which supports String / Array of bytes / ArrayBuffer / Uint8Array / Buffer / Blob / Promisedecompression of compressed packages in file formats.
Since the interface returns a file stream, use jszip-utilsthe package to convert the file stream into ArrayBuffera format.

npm install jszip -S
npm install jszip-utils -S
import JSZipUtils from "jszip-utils";
import JSZip from "jszip";

export default {
    
    
	data(){
    
    
		return {
    
    
			zip: null,
		}
	},
  	methods:{
    
    
		loadZip() {
    
    
	      JSZipUtils.getBinaryContent("压缩文件地址", function (err, data) {
    
    
			   if(err) {
    
    
			      throw err; // or handle the error
			   }
			   this.zip = new JSZip();
			   //解压
			   this.zip.loadAsync(data).then((res) => {
    
    		
	              console.log(res);
	            });
			});
	    },
	}
}

It prints out like this:

jszip

2. Generate directory

The directory uses element-uia tree control, and the loading method is lazy, so that all directories do not need to be generated recursively.

<el-tree
  ref="tree"
  lazy
  highlight-current
  :data="fileMenu"
  :props="defaultProps"
  :load="loadNode"
  @node-click="handleNodeClick"
>
  <!-- 文件夹图标 -->
  <span class="custom-tree-node" slot-scope="{ node, data }">
    <em v-if="!data.leaf" class="el-icon-folder-opened"></em>
    <span>{
   
   { node.label }}</span>
  </span>
</el-tree>
data(){
    
    
	return {
    
    
		fileMenu: [],
		defaultProps: {
    
    
	        children: "children",
	        label: "label",
	        isLeaf: "leaf",
	    },
	}
},
methods:{
    
    
	getMenuList(zip) {
    
    
		const menu = [];
		// 循环当前文件夹目录
		zip.forEach((relativePath, file) => {
    
    
		   const dir = relativePath.split("/");
		   // 文件
		   if (dir.length === 1) {
    
    
		     menu.push({
    
    
		       label: dir[0],
		       leaf: true,
		       path: file.name,
		     });
		   }
		   // 文件夹
		   if (dir.length === 2 && file.dir) {
    
    
		     menu.push({
    
    
		       label: dir[0],
		       leaf: false,
		       path: file.name,
		     });
		   }
	 });
	 return menu;
	},
	// 加载子目录
	loadNode(node, resolve) {
    
    
	  if (node.level === 0) return;
	  // 把点击的文件夹路径传入
	  const child = this.getMenuList(this.zip.folder(node.data.path));
	  resolve(child);
	},
}

3. Code editing

Online code editing requires monaco-editor , it is recommended to download version 0.30.0. If you need code highlighting, shortcut keys, syntax prompts and other functions, you can install monaco-editor-webpack-plugina plug-in to help import.

npm install [email protected] -S
npm install [email protected] -S
<template>
	<div id="monaco"></div>
</template>

<script>
import * as monaco from "monaco-editor";
export default {
      
      
	data(){
      
      
		return {
      
      
			monacoInstance: null,
		}
	},
	mounted(){
      
      
		this.monacoInstance = monaco.editor.create(
		  document.getElementById("monaco"),
		  {
      
      
		    value: `//请选择文件进行编辑`,
		    language: "js",
		  }
		);
		// 编辑监听
	    this.monacoInstance.onDidChangeModelContent(() => {
      
      
	      this.saveValue();
	    });
	},
	methods:{
      
      
		// 在树节点加上点击事件
		handleNodeClick(data) {
      
      
		  if (data.leaf) {
      
      
		  	this.currentPath = data.path;
		  	// 将点击的文件内容显示在编译框内
		     this.zip
		       .file(data.path)
		       .async("string")
		       .then((res) => {
      
      
		         this.monacoInstance.setValue(res);
		       });
		   }
		 },
		 // 保存编辑
		 saveValue() {
      
      
	      if (this.currentPath) {
      
      
	        const newValue = this.monacoInstance.getValue();
	        this.zip.file(this.currentPath, newValue);
	      }
	    },
	    // 打包
	    pack(){
      
      
			this.zip.generateAsync({
      
      type:"blob"})
				.then(function (content) {
      
      
				    // 保存或上传操作
				    // saveAs(content, "hello.zip");
				});
		}
	}
}
</script>

Guess you like

Origin blog.csdn.net/m0_49343686/article/details/126096785