大家好,我们继续来进行基于 JMeter 的自动化测试平台的开发实战。
上次的教程中,我们已经完成了工程开发环境的搭建,那么现在我们可以进入到代码,今天先以一个简单的例子,来带着大家熟悉一下。

历史文章

手把手教你基于 JMeter 开发一个自动化测试平台 (1)

今天的目标

我们先来明确一下今天的目标,我们要选择一个相对简单的目标来作为入门,通过这个过程来熟悉技术栈、项目和开发流程。
经过一番斟酌,我选择的目标是开发一个新的用户信息页面,因为一来 MeterSphere 这个工程中原来的用户信息页面不是太好看,二来这个功能相对简单,不涉及太多的业务内容,比较适合上手。

原型设计

现在系统里面个人信息的页面是长这个样子的,我们就来改造一下这个页面,来一边学习一边熟悉项目。

今天我们的内容主要针对前端部分。

这里我们来做一下原型设计,大概做成下面这样。

梳理任务

准备好助手

再开始之前,我们要先准备几个助手,也就是先打开几个相关的文档,可以随时查阅。这次的内容主要关联的都是前端部分,所以只准备前端的即可。

接下我们就开始吧

首先我们要做的第一件事是先分析一下代码,就像咱们开始的时候书的一样,我们是在一个开源项目的基础上来进行开发和学习,那么我们要更多的利用项目已经是做的内容。

导航栏和基本页面

第一步我们先来添加顶部的导航信息。
这里我们要找到顶部导航栏位置。他的具体文件位置如下:

接下来,我们就在里面加入我们的飞致云学堂导航链接。 当中加入如下:

<el-menu-item index="/class" onselectstart="return false"> {{$t('commons.class')}} </el-menu-item>

我们会发现 $t('commons.class') 的代码,这是因为项目已经进行了多语言的处理,我们也遵循规则,使用多语言的方式,接下来我们就到 i18n 的文件中添加对应的配置,文件位置在:

metersphere/frontend/src/i18n/zh-CN.js

多语言的内容这里我们演示一次,后续的内容中就不再重复介绍。

在上面添加顶部导航栏的时候,我们添加了一条路由 /class ,那么我们接下来就来配置这条路由信息。项目的前端路由信息都在如下文件中配置:

metersphere/frontend/src/business/components/common/router/router.js

我们给自己添加一块路由信息,后面我们其他示例的路由信息也都放在 /class 下:

{
  path: "/class",
  components: {
    content: Class
  }
}

接下来,我们再来创建/ class 路由对应的页面,我们也给自己创建一个专门的文件夹:

metersphere/frontend/src/business/components/class

之后我们通过 IDE 直接创建一个 VUE 文件 ,Class.vue ,然后随便写点内容,像下面这样:

<template>
    <div>
      <span>111111</span>
    </div>
</template>

<script>
    export default {
        name: "Class"
    }
</script>

<style scoped>

</style>

那么添加好了信息之后,我们来刷新一下页面,会发现顶部的导航已经出来了,点击一下,是一个只有 11111 的页面。

添加左侧菜单

因为我们后续还会添加其他内容,所以这里我给我们的页面再加入一个左侧菜单。
这里我们可以参考 MeterSphere 已经开发好的左侧菜单,多利用一下已经做好的组件。我们修改一下 Class.vue:

<template>
  <ms-container>

    <ms-aside-container>
      <ms-new-current-user/>
      <el-divider/>
      <h1>{{$t('commons.class')}}</h1>
      <class-menu/>
    </ms-aside-container>

  </ms-container>
</template>

<script>
  import MsAsideContainer from "../common/components/MsAsideContainer";
  import MsContainer from "../common/components/MsContainer";
  import MsMainContainer from "../common/components/MsMainContainer";
  import MsCurrentUser from "../settings/CurrentUser";
  import ClassMenu from "./ClassMenu";
  export default {
    name: "Class1",
    components: {MsContainer, MsAsideContainer, MsCurrentUser, ClassMenu},
  }
</script>

<style scoped>
</style>

现在我们的代码长这个样子了,这里我们用到了项目中已经开发好的几个组件,MsContainer, MsAsideContainer, MsNewCurrentUser,主要要在 script 部分引入和声明各个组件。
然后我们自己再写一个自己的菜单内容组件 ClassMenu。

<template>
  <el-menu menu-trigger="click" :default-active="$route.path" router>
      <el-menu-item index="/class/userMsg">{{$t('commons.personal_info')}}</el-menu-item>
  </el-menu>
</template>

<script>
  import {checkoutCurrentOrganization, checkoutCurrentWorkspace} from "../../../common/js/utils";
  export default {
    name: "ClassMenu",
    data() {
      return {
        isCurrentOrganizationAdmin: false,
        isCurrentWorkspaceUser: false,
      }
    },
    mounted() {
      this.isCurrentOrganizationAdmin = checkoutCurrentOrganization();
      this.isCurrentWorkspaceUser = checkoutCurrentWorkspace();
    },
  }
</script>

<style scoped>
  .el-menu {
    border-right: 0;
  }
  .el-menu-item {
    height: 40px;
    line-height: 40px;
  }
  .icon {
    width: 24px;
    margin-right: 10px;
  }
  .account {
    color: #5a78f0;
  }
  .organization {
    color: #b33a5b;
  }
  .workspace {
    color: #44b349;
  }
</style>

这里我们借用了项目中已经有的组件,来处理系统中切换组织和工作空间的逻辑。
接下来,我们在看刷新一下页面,可以看到变成了这个样子

个人信息页面

在有了左侧菜单之后,我们就来完成菜单跳转的个人信息页面。
我们先在 class 文件夹下创建 UserMsg.vue

metersphere/frontend/src/business/components/class

我们先把代码贴出来:

<template>
  <div v-loading="result.loading">
    <el-card class="box-card" shadow="hover">
      <div slot="header" class="clearfix">
        <span>个人信息</span>
        <el-button style="float: right; padding: 3px 0" type="text">编辑</el-button>
      </div>
      <el-row :gutter="20">
        <el-col :span="6"><div class="grid-content bg-purple" align="center">
          <div class="block">
            <el-image
              style="width: 100px; height: 100px"
              :src="userData.img"
              fit="contain"></el-image>
          </div>
        </div></el-col>
        <el-col :span="18"><div class="grid-content bg-purple">
          <el-form ref="form" :model="form" label-width="">
            <el-form-item label="ID">
              <span>{{userData.id}}</span>
            </el-form-item>
            <el-form-item :label="$t('commons.username')">
              <span>{{userData.name}}</span>
            </el-form-item>
            <el-form-item :label="$t('commons.email')">

              <span>{{userData.email}}</span>
            </el-form-item>
            <el-form-item :label="$t('commons.phone')">
              <span>{{userData.phone}}</span>
            </el-form-item>
              <el-form-item :label="$t('commons.create_time')">
              <span>{{userData.createTime}}</span>
            </el-form-item>
                <el-form-item :label="$t('commons.operating')">
              <template>
                <ms-table-operator-button type="primary" circle :tip="$t('member.edit_information')" icon="el-icon-edit"
                           @user1="edit(userData)" />
              </template>
            </el-form-item>
          </el-form>
        </div></el-col>
      </el-row>
    </el-card>
  </div>
</template>
<script>
    import {getCurrentUser} from "../../../common/js/utils";
    import MsTableOperatorButton from "../common/components/MsTableOperatorButton";

    export default {
      name: "UserMsg",
      components:{MsTableOperatorButton},
      data(){
          return {
            result: {},
            userData:{},
            updateVisible : false,
            editPasswordVisible : false,
            isLdapUser:false,

            form:{}
          };
      },
      methods:{
        currentUser: () => {
          return getCurrentUser();
        },
        initMsg(){
          this.result = this.$get("/user/info/" + this.currentUser().id, response => {
            let data = response.data;

            this.isLdapUser = response.data.source === 'LDAP' ? true : false;
            this.userData = data;
          })
          this.result.loading = true;
        },edit(userdata) {

        },handleClose: () => {

        },updateUser(updateUserForm) {

        },
      },
      activated() {
          this.initMsg();
      }
    }
</script>
<style scoped>
</style>

我们分页面模板和 JS 来看一下。

接下来我们再添加一下路由信息,现在是这个样子:

{
      path: "/class",
      components: {
        content: Class
      },
      children: [
        {
          path: 'userMsg',
          component: UserMsg,
        }
        ]
    },

注意在上面要 import 一下 userMsg

import Class from "../../class/Class";
import UserMsg from "../../class/UserMsg";

我们再来刷新一下页面,现在点击左侧的菜单,可以看到我们的页面了。

到这里,我们已经有了一个新的页面的雏形,因为篇幅所限,今天我们的分享就先到这里,下次我们继续来完善修改信息,上传,后端等部分的内容。


↙↙↙阅读原文可查看相关链接,并与作者交流