Objective of this paper: To build a VS Code plug-in that supports embedded web pages, to realize automatic generation of front-end form Code of Vue project, and to realize the freedom of touch as soon as possible.
Results show
Without further ado, let’s take a look at the final work:
After watching the GIF is not refreshing so didiao, let’s get started ~~
Step 1
First of all, we need an open source visual designer for drag-and-drop design. We searched GitHub and code cloud, and we already have a lot of finished products, including various form-create, form-Design, vue-Form, form-Generator, etc.
Second, filter from the above designer support code generation, of course, if there is no code generation can be implemented, after all, is not open source?
VForm GitHub is an open source VForm designer. Haha… It looks familiar, but it’s a little bit more functional
Step 2
Install VS Code Plug-in Development suite:
npm install -g yo generator-code
Copy the code
After successful installation, run Yo Code to generate a new plug-in project:
Use a simple and pleasant name — Quick-coder, add a simple description, and select the other options as needed.
Take a look at the generated plug-in project:
There are only two files to focus on here: extension.js and package.json
Extension.js, plug-in extension point description file package.json, project properties, dependency packages, and plug-in configuration file
The second step is over, and the third step is to implement the plug-in coding.
Step 3
Modify package.json to add startup commands for the plug-in, which can be launched from the command panel and the left explorer.
"contributes": {
"commands": [{
"command": "extension.openVFormMaker"."title": "Open VForm Designer"}]."menus": {
"explorer/context": [{
"command": "extension.openVFormMaker"."group": "navigation"}}},Copy the code
Modify the extension.js plug-in enablement method with just one line:
function activate(context) {
require('./src/vform-loader')(context)
}
Copy the code
At this point, we haven’t explained how the entire code generator plug-in works, but now it’s time to tell. We want a WebView panel to open when the plug-in starts, the WebView panel to load the VForm web page via URL configuration parameters, and VS Code to postMessage when the VForm generates Code, which VS Code is responsible for saving as a local file. The key code to implement the above requirements is in the vform-loader.js file.
Here are two more trivia questions to answer:
- Can WebView load remote web pages directly? The answer is no, you can only load local HTML files.
- So the question is, right? How does a WebView load the HTML of a remote web page? The answer is simply to embed iframe in the local HTML file. Iframe is versatile – YYDS!
With these small cases solved, let’s take a look at the soul code of the plug-in.
src\view\index.html
<! DOCTYPEhtml>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width,initial-scale=0,maximum-scale=0,user-scalable=yes,shrink-to-fit=no"
/>
<title>Quick Coder</title>
</head>
<body>
<iframe id="frame" width="100%" height="100%" frameborder="0"></iframe>
<script>
window.onload = function () {
const vscode = acquireVsCodeApi();
const cmds = {
setSrc: function (message) {
var frame = document.getElementById("frame");
frame.src = message.data.src;
},
writeFile: function (message) {
vscode.postMessage(message);
},
openUrl: function (message) {
vscode.postMessage(message);
},
setStorageItem: function (message) { vscode.postMessage(message); }};window.addEventListener("message".(event) = > {
const message = event.data;
if (message && message.cmd) cmds[message.cmd](message);
});
};
</script>
</body>
</html>
Copy the code
src\vform-loader.js
const vscode = require('vscode')
const fs = require('fs')
const path = require('path')
const open = require('open')
const DB_PATH = path.join(__dirname,'./data/db.json')
function getExtensionFileAbsolutePath(context, relativePath) {
return path.join(context.extensionPath, relativePath)
}
/** * Reads HTML content from an HTML file that can be loaded by the Webview *@param {*} Context *@param {*} TemplatePath the HTML file relative to the plug-in root directory */
function getWebViewContent(context, templatePath) {
const resourcePath = getExtensionFileAbsolutePath(context, templatePath)
const dirPath = path.dirname(resourcePath)
let html = fs.readFileSync(resourcePath, 'utf-8')
// vscode does not support direct loading of local resources, so it needs to be replaced with its own path format. Here we simply replace the style and JS path
html = html.replace(/(.(m, $1, $2) = > {
return $1 + vscode.Uri.file(path.resolve(dirPath, $2)).with({ scheme: 'vscode-resource' }).toString() + '"'
})
return html
}
const methods = {
writeFile: function (message, vscode, dirPath) {
let { fileName, code } = message.data
let filePath = path.join(dirPath, fileName)
fs.writeFileSync(filePath, code)
vscode.window.showInformationMessage(` file${fileName}Create success ')},openUrl: function (message, vscode, dirPath) {
open(message.data.url)
},
setStorageItem: function(message, vscode, dirPath) {
const { key, val } = message.data
const str = fs.readFileSync(DB_PATH).toString()
let json = {}
if (str) {
json = JSON.parse(str)
}
json[key] = val
fs.writeFileSync(DB_PATH, JSON.stringify(json))
},
}
module.exports = function (context) {
context.subscriptions.push(vscode.commands.registerCommand('extension.openVFormMaker'.(uri) = > {
if (uri) {
let dirPath = uri.fsPath,
stat = fs.lstatSync(dirPath)
if (stat.isFile()) dirPath = path.dirname(dirPath)
let pclintBar = vscode.window.createStatusBarItem()
pclintBar.text = 'Target folder:${dirPath}`
pclintBar.show()
const panel = vscode.window.createWebviewPanel(
'vFormMaker'.VForm Form Designer,
vscode.ViewColumn.One,
{
enableScripts: true.// Enable JS, disabled by default
retainContextWhenHidden: true.// WebView remains in state when hidden to avoid being reset
}
)
panel.onDidChangeViewState(e= > {
if (panel.visible) {
pclintBar.show()
} else {
pclintBar.hide()
}
})
panel.webview.html = getWebViewContent(context, 'src/view/index.html')
panel.webview.postMessage({
cmd: 'setSrc'.data: {
src: vscode.workspace.getConfiguration().get('VFormMaker.url') + '&t=' + new Date(),
db: JSON.parse(fs.readFileSync(DB_PATH).toString() || '{}')
}
})
panel.webview.onDidReceiveMessage(message= > {
if (message.cmd && message.data) {
let method = methods[message.cmd]
if (method) method(message, vscode, dirPath)
} else {
vscode.window.showInformationMessage('No method corresponding to the message')}},undefined, context.subscriptions)
panel.onDidDispose(e= > {
pclintBar.dispose()
})
} else {
vscode.window.showInformationMessage('Cannot get folder path')}}}))Copy the code
OK~ grey often good, give a big hand to see here πππ, soon to see the effect of the plugin!!
Finally modify package.json file contributes attribute, add URL parameter configuration, complete!!
"contributes": {
"configuration": {
"type": "object"."title": "VForm Designer Configuration"."properties": {
"VFormMaker.url": {
"type": "string"."default": "Http://120.92.142.115/? vscode=1"."description": "VForm Designer remote URL"}}},Copy the code
Press F5 in VS Code to debug the plugin and enjoy your work π€π€~~~
Step 4 / Package and publish
Install the vsCE packaging tool
npm install -g vsce
Copy the code
Run the vsce package command in the plug-in project to generate a.vsix file (you will be prompted to modify the readme. md file to add an introduction and instructions for the plug-in).
vsce package
Copy the code
Sign up for a VS Marketplace account, upload a.vsix file, and make it available to all VS Code users: VS Marketplace
The latter/Finally
As a brief review, we embedded VForm remote web pages through WebView, realizing common Vue form front-end code generation (support Vue2 also support Vue3 oh) expected requirements, because VForm itself is an open source project, and has good scalability, interested big people can freely extend VForm functions. Further realization of el-table and other components of the front-end code automatic generation, as soon as possible to achieve fish free πΊπΊπΊ
The last
For those who feel a little tired of writing their own plug-ins, you can search vform-Maker or vformAdmin directly in the VS Code extension
Finally, attach the VForm link of GitHub, the world’s largest gay dating website: Gitee