vue实战

vue仿dos命令界面

2022-01-21 13:48:40 更新   浏览量: 416
上一章:vue+element-ui 实现可编辑表格 下一章:Vue使用sm-crypto国密加密、解密介绍

业务需求

vue项目中弹出窗口,在窗口中执行dos命令

技术栈

  • vue + nodejs(child_process+koa)
  • child_process是nodejs的子进程模块,child_process.exec可创建shell,然后在shell里执行命令。然而,child_process并不在webpack打包中,页面中打印child_process是一个不包含任何方法的空对象{},因此需要用nodejs做服务端,使用koa作为中间件。
  • 服务端:cmd.js

  • const Koa = require("koa"); // 引入koa
    const Router = require("koa-router"); // 引入koa-router
    
    const app = new Koa(); // 创建koa应用
    const router = new Router(); // 创建路由,支持传递参数
    
    const bodyParser = require("koa-bodyparser"); // 处理post请求
    app.use(bodyParser()); // 配置post bodyparser的中间件
    
    const cors = require("koa-cors"); // 设置跨域
    app.use(cors()); // 全部允许跨域
    
    const iconv = require("iconv-lite"); // iconv进行转码
    iconv.skipDecodeWarning = true;
    
    const child_process = require("child_process");
    
    // 对exec进行封装,返回一个Promise对象,便于处理
    function doShellCmd(cmd) {
      let str = cmd;
      let result = {};
      return new Promise(function(resolve, reject) {
        child_process.exec(str, { encoding: "binary" }, function(
          err,
          stdout,
          stderr
        ) {
          // console.log(iconv.decode(stdout, "cp936"));
          if (err) { // 失败时也返回失败的回文
            result.errCode = 200;
            result.data = {
              data: iconv.decode(stdout, "cp936"),
              success: "200",
              message: "失败"
            };
            if (result.data.data === "") {
              result.data.data = `’${
                str.split(" ")["0"]
              }’不是内部或外部命令,也不是可运行的程序或批处理文件`;
            }
            resolve(result);
          } else { // 成功时返回回文
            result.errCode = 200;
            result.data = {
              data: iconv.decode(stdout, "cp936"),
              success: "200",
              message: "成功"
            };
            resolve(result);
          }
        });
      });
    }
    
    // api
    router.post("/koa/action/doShellCmd", async ctx => {
      // console.log(ctx.request.body.cmd);
      let result = await doShellCmd(ctx.request.body.cmd); // 调用exec
      ctx.response.status = result.errCode;
      ctx.response.body = result.data;
    });
    
    app.use(router.routes());
    app.listen(3000);
    console.log("app started at port 3000...");
  • 本地启动服务,打印出app started at port 3000...,说明本地启动成功。

  • 接口:api.js

    import axios from "axios"; // 这里是封装好的axios,若未封装可单独引入并使用
    
    // 执行命令语句
    export const doShellCmd = data => {
      return axios.request({
        url: "/koa/action/doShellCmd",
        data,
        method: "post"
      });
    };

    记得配置跨域请求

  • vue.config.js文件
    module.exports = {
      ......
      ......
      devServer: {
        proxy: {
          '/api': {
            target: 'https://www.qianduan.cn/api',
            changeOrigin: true,
            pathRewrite: {
              '^/api': ''
            }
          }
        }
      }
    };

    配置好之好后重启项目

  • 客户端:cmd.vue

    <template>
      <el-dialog class="cmd-dialog"
                 title="常用工具"
                 :visible.sync="dialogVisibleCmd"
                 top="10vh"
                 @close="closeCmd">
    
        输入命令:
        <el-input v-model="command"
                  @keyup.enter.native="optionCmd"
                  :disabled="contentLoading"
                  style="width:300px">
        </el-input>
        <el-button type="warning"
                   size="medium"
                   @click="resContent='';command=''"
                   :disabled="contentLoading"
                   style="float:right">清空</el-button>
        <el-button type="success"
                   size="medium"
                   @click="optionCmd"
                   :disabled="contentLoading"
                   style="float:right;margin-right:10px">执行</el-button>
    
        <p v-html="resContent"
           v-loading="contentLoading"
           element-loading-text="连接中"
           element-loading-spinner="el-icon-loading"
           element-loading-background="rgba(0, 0, 0, 0.8)"
           style="margin:20px 0 10px 0;white-space:pre-wrap;background:#000;color:#fff;padding:10px;height:400px;overflow:auto"></p>
    
      </el-dialog>
    </template>
    
    <script>
    import { doShellCmd } from "@/api/api.js";
    
    export default {
      data () {
        return {
          dialogVisibleCmd: false, // dialog是否可见
          command: "", // cmd命令
          resContent: "", // cmd结果
          contentLoading: false
        };
      },
      methods: {
        // 打开dialog
        openCmd () {
          this.dialogVisibleCmd = true;
        },
        // 执行ssh
        async optionCmd () {
          this.resContent = "";
          this.contentLoading = true;
          this.resContent = (await doShellCmd({ cmd: this.command })).data.data;
          this.contentLoading = false;
        },
        // 关闭dialog
        closeCmd () {
          this.command = "";
          this.resContent = "";
          this.contentLoading = false;
        }
      }
    };
    </script>
    
    <style rel="stylesheet/scss" lang="scss" scoped>
    </style>

    最终运行效果如下图:

  • 更多Vue基础教程、插件,请访问www.qianduan.cn 前端教程

扫二微码
上一章:vue+element-ui 实现可编辑表格 下一章:Vue使用sm-crypto国密加密、解密介绍

最近更新 免责声明 关于我们

Copyright © 2004-2021 前端教程 qianduan.cn All Rights Reserved   陕ICP备2021014585号-1 陕公网安备 61012402000223号 前端教程

友情链接:  前端工具 前端插件