测试需求平台5-Blueprint优化与首个vue页搭建

✍此系列为整理分享已完结入门搭建《TPM提测平台》系列的迭代版,拥抱Vue3.0将前端框架替换成字节最新开源的arco.design,其中约60%重构和20%新增内容,定位为从

0-1手把手实现简单的测试平台开发教程,内容将囊括基础、扩展和实战,由浅入深带你实现测试开发岗位中平台工具技术能力入门和提升。

1.优化TPMService结构

之前实现的接口代码全部写在主运行文件中,随着业务接口的增多这显示是不合理,所以这里利用上篇学到的 Blueprint 来进行优化,使其模块化的管理和开发。

1.1 迁移登录代码

在项目初始化的文章里。我们已经在TPMService项目跟目录创建了apis包文件夹,用于所有分业务接口管理,因此对于用于接口创建一个命名为user.py的Python文件,并将之前 run.py 中登录、获取用户信息、登出的代码剪切到 user.py,另外需要从flask中import blueprint,并注册一个对象,重点实现给出标记使用的新的接口类/apis/user.py和蓝图对象优化后的完整代码参考如下:

python 复制代码
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
from flask import request
import json

from flask import Blueprint

'''
@Author: Zhang Qi
@Copyright: 博客&公众号《大奇测试开发》
@Describe: 用户登录接口
'''

app_user = Blueprint("app_user", __name__)

@app_user.route("/api/user/login",methods=['POST'])
def login():
    data = request.get_data() # 获取post请求body数据
    js_data = json.loads(data) # 将字符串转成json

    if 'username' in js_data and js_data['username'] == 'admin':
        result_success = {"code":20000,"data":{"":""}}
        return result_success
    else:
        result_error = {"code":60204,"message":"账号密码错误"}
        return result_error

@app_user.route("/api/user/info",methods=['GET'])
def info():
    # 获取GET中请求token参数值
    token = request.args.get('token')
    if token == 'admin-token':
        result_success = {
            "code":20000,
            "data":{
                "roles":["admin"],
                "role":"admin", # 兼容Aroc前端框架
                "introduction":"I am a super administrator",
                "avatar":"https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif",
                "name":"大奇",
                "jobName": '非典型程序员',
                }
            }
        return result_success
    else:
        result_error = {"code": 60204, "message": "用户信息获取错误"}
        return result_error

@app_user.route("/api/user/logout", methods=['POST'])
def logout():
    result_success = {
        "status": 'ok',
        "msg": '请求成功',
        "code": 20000,
    }
    return result_success

然后就是在app.py进行Blueprint的注册,重新运行做以下接口请求验证(测试略)是否均正常响应

2.产品管理之展示

我们接下来将正式开始实现产品管理页面的交互逻辑,因为涉及到很多新内容,也是全系列的基础,所以会通过较多几篇分享来讲解。

2.1 产品列表接口

按照上边的优化结构练习,我们创建一个硬编码的一个产品线模块 /apis/product.py ,来配合实现一个"产品列表"vue页面,直接给出核心代码:

python 复制代码
# -*- coding:utf-8 -*-
from flask import Blueprint

app_product = Blueprint("app_product", __name__)

@app_product.route("/api/product/list",methods=['GET'])
def product_list():
    # 硬编码返回list
    data = [
        {"id":1, "keyCode":"project1", "title":"项目一", "desc":"这是项目1描述", "operator":"admin","update":"2020-04-06"},
        {"id":2, "keyCode": "project2", "title": "项目二", "desc": "这是项目2描述", "operator": "user", "update": "2020-04-03"}
    ]
    # 按返回模版格式进行json结果返回
    resp_data = {
        "code": 20000,
        "data": data
    }

    return resp_data

不要忘记 app.pyregister_blueprint 注册

python 复制代码
# -*- coding:utf-8 -*-
from flask import Flask
from apis.user import app_user
from apis.product import app_product
from flask_cors import CORS

app = Flask(__name__)
CORS(app, supports_credentials=True)

app.register_blueprint(app_user)
app.register_blueprint(app_product)

if __name__ == '__main__':
    app.run(debug=True)

2.2 搭建第一Arco Vue页

在路径TPMArco/src/views/下创建个文件夹product, 接着右键 New Vue Compoent,命名为 index.vue,在自动生成的模版页面代码

要想页面展示还需要配置路由菜单,在Acro Pro的经过验证是src/router/routes/modules创建对应的路有来实现,这里我给出正确的配置,以便先实现第一个页面的搭建,具体 菜单和路由 后边拎出个小节点单独说

还有最后一个配置,需要在 src/locale/zh-CN.ts 增加locale的定义,因为目前的脚手架是多语言的,菜单这块需要使用 语言包键名 才能正确展示。

typescript 复制代码
import localeSettings from './zh-CN/settings';

export default {
  'menu.config': '基础管理',
  'menu.config.product': '产品线管理',
  ...
};

2.3 使用第一组件

利用上边的页面和接口,我们通过一个Table组件来实现产品列表展示,所谓万事开通难,先看下官方<a-table>的基础使用

arco.design/vue/compone...

点击</>按钮展开参考代码,将其对应和

typescript 复制代码
<template>
  <a-table :columns="columns" :data="data" />
    </template>

<script>
    // reactive是 Vue3 中提供的实现响应式数据的方法
    import { reactive } from 'vue';

export default {
  name: "Product",
  setup() {
    // 定义表格列
    const columns = [
      {
        title: 'Name',
        dataIndex: 'name',
      },
      {
        title: 'Salary',
        dataIndex: 'salary',
      },
      {
        title: 'Address',
        dataIndex: 'address',
      },
      {
        title: 'Email',
        dataIndex: 'email',
      },
    ];
    // 表格数据,这里先不请求后端写死模拟
    const data = reactive([{
      key: '1',
      name: 'Jane Doe',
      salary: 23000,
      address: '32 Park Road, London',
      email: 'jane.doe@example.com'
    }, {
      key: '2',
      name: 'Alisa Ross',
      salary: 25000,
      address: '35 Park Road, London',
      email: 'alisa.ross@example.com'
    }, {
      key: '3',
      name: 'Kevin Sandra',
      salary: 22000,
      address: '31 Park Road, London',
      email: 'kevin.sandra@example.com'
    }, {
      key: '4',
      name: 'Ed Hellen',
      salary: 17000,
      address: '42 Park Road, London',
      email: 'ed.hellen@example.com'
    }, {
      key: '5',
      name: 'William Smith',
      salary: 27000,
      address: '62 Park Road, London',
      email: 'william.smith@example.com'
    }]);
    
    return {
      columns,
      data
    }
  },
}
</script>

<style scoped>
  </style>

通过 command(ctrl)+ s 保存代码,如果是IDE在npm run dev 会自动编译渲染,如果没有请重新运行命令,最终看到上述给定的表格(写死在前端的数据)正常显示,至此第一个组件使用完成。

2.4 使用后端接口

1)配置查询查询API

src/api/product.ts 创建一个接口配置文件,配置上边服务的get请求地址,其中定义方法名为apiProductList(), 具体代码如下:

typescript 复制代码
# src/api/product.ts

import axios from 'axios';
import type { TableData } from '@arco-design/web-vue/es/table/interface';

export function apiProductList() {
  return axios.get<TableData[]>('/api/product/list');
}

特别说明:由于Acro拥抱typescript,所有组件的pro的例子代码都是,所以为了拿来即用,后续的前端js部分代码也会沿用,好在如果会javacript过渡不会很难,笔者也是第一次使用,从照葫芦画瓢的基础上会帮助先趟坑,因此完全不用但心,拥抱技术,也是一种全新的尝试。

2)Table远程数据绑定

这块笔者首次接触折腾了一上午,Vue3.0语法使用上对比2.0还是有不少不同,其中<script lang="ts" setup> 语法糖就是新的变化,本篇先不过多说明,有兴趣可以提前看引用中文章。

Vue3之script-setup解析 www.jianshu.com/p/5096bfb42...

如果你曾经写习惯了vue2.0中 methods:{}data()create (),就像电影里张无忌学习太极时候一样暂时忘掉,以下是完整可运行代码:

typescript 复制代码
<template>
  <a-table
    :columns="columns"
    :data="renderList"
    :pagination="false"
  />
</template>

<script lang="ts" setup>
// 引用接口方法
import { apiProductList } from '@/api/product';

// vue ref获取组件
import { ref } from "vue";
import { TableData } from "@arco-design/web-vue/es/table/interface";

// 表格列属性
const columns = [
  {
    title: 'ID',
    dataIndex: 'id',
  },
  {
    title: '标识码',
    dataIndex: 'keyCode',
  },
  {
    title: '标题',
    dataIndex: 'title',
  },
  {
    title: '描述',
    dataIndex: 'desc',
  },
  {
    title: '操作者',
    dataIndex: 'operator',
  },
  {
    title: '更新时间',
    dataIndex: 'update',
  }
]

// 定义指定标准表返回格式变量,并通过async箭头函数异步请求接口方法
const renderList = ref<TableData[]>();
const fetchData = async () => {
  try {
    const { data } = await apiProductList();
    renderList.value = data;
  } catch (err) {
    console.log(err);
  }
};
fetchData();
</script>

<script lang="ts">
  export default {
name: 'Product',
};
</script>

此内容中我们还是需要了解一下几点

  • vue 是一套响应式框架,一般组件、方法和样式在一个页面中集中实现
  • 模块 组件UI实现区域
  • 模块 业务实现的区域

3)运行测试

以上如果没有错误的话,我们再重新运行后端服务,

shell 复制代码
python app.py  # 或PyCharm 配自run config直接运行
nmp run dev    # 或WebStorm 配自run config直接运行

前端服务看下效果,接口正确请求,数据正确渲染到table组件上。

3.菜单和路由

路由通常都和菜单绑定在一起,为了减少维护的量,我们直接通过路由表生成了菜单,以下内容均来在官方文档。

官方文档 arco.design/vue/docs/pr...

3.1 路由

首先,需要先了解一下路由表的配置。基本的路由配置请参阅 Vue-Router 官方文档

typescript 复制代码
// const DEFAULT_LAYOUT = () => import('@/layout/default-layout.vue');

// 在本例子中,页面最终路径为 /dashboard/workplace
export default {
 path: 'dashboard', // 路由路径
 name: 'Dashboard', // 路由名称
 component: () => import('@/views/dashboard/index.vue'), // 跳转的组件页面
 // component: DEFAULT_LAYOUT,  // Aroc pro 一级菜单用默认布局包裹
 meta: {
   locale: 'menu.dashboard',
   requiresAuth: true, 
   icon: 'icon-dashboard',
   order: 0,
 },
 children: [ // 子菜单
   {
     path: 'workplace',
     name: 'Workplace',
     component: () => import('@/views/dashboard/workplace/index.vue'),
     meta: {
       locale: 'menu.dashboard.workplace',
       requiresAuth: true,
       roles: ['admin'],
       hideInMenu: false,
     },
   },
 ],
};

路由 Meta 元信息(官方还有一些其他几个参数,目前用不到就不罗列了)

  • roles : 配置能访问该页面的角色,如果不匹配,则会被禁止访问该路由页面
  • requiresAuth: 是否需要登录鉴权
  • locale:一级菜单名(语言包键名)
  • icon:菜单配置icon
  • hideInMenu:是否在左侧菜单中隐藏该项
  • order:排序路由菜单项。如果设置该值,值越高,越靠前

这里想要说下Acro Pro模版项目如何设置一级菜单,笔者大奇尝试了一些配置,以及搜索了一番均无果,如果大家对这块熟悉有配置方式请告诉我,如果后续我发现了解决办法也会第一时间分享出来。

3.2 菜单

前端菜单生成过程:

  • 通过 appRoute 计算属性,得到带有路由信息的路由树。
  • 使用上一步获取的路由信息进行权限过滤,生成用于渲染的 菜单树
  • 通过 渲染 菜单树,递归生成菜单。

服务端菜单生成过程:

  • 在Store中增加api请求的 action,用于获取服务端的路由配置。
  • 发起请求,将服务端的路由配置结果存储在Store中。
  • 通过 appRoute 计算属性,得到带有路由信息的路由树。
  • 使用上一步获取的路由信息进行权限过滤,生成用于渲染的 菜单树
  • 通过 渲染 菜单树,递归生成菜单。

遇到的问题

笔者在编程过程中遇到了大量如下的警告报错,经查询是 ts格式的检查和eslint一样,如果里边没有对应的error是不会出现如下页面报错,只会在控制台输出警告,但如果确实烦可以在 .eslintrc.js 的rules配置注释掉它,或者进行标准格式化 (Alt-Shift-Cmd-P on macOS or Alt-Shift-Ctrl-P on Windows and Linux)、或IDE配置保存后自动格式化均可。

本篇最后来个回顾,主要有了好多的第一次:

  • 后端接口路由的分类优化
  • 一个Acro vue 新页面的诞生
  • Acro design 第一个组件使用
  • 实现接口请求和数据绑定
  • 菜单\路由配置和扩展参数说明

由于是再版整理,我一开始以为会很快,但实际上这里涉及了新风格框架,及vue3、typescript新内容,实现和验证以上所有内容的时候还是花了近一天多的时间,这里想说的是在互联网快速发展的今天,接触的新的东西不可避免,要保持好奇、敢尝试的一种精神不断的充实自己,当然这个精力和度要自己把握好。

相关推荐
滚雪球~4 分钟前
@vue/cli启动异常:ENOENT: no such file or directory, scandir
前端·javascript·vue.js
GDAL14 分钟前
vue3入门教程:ref函数
前端·vue.js·elementui
GISer_Jing23 分钟前
Vue3状态管理——Pinia
前端·javascript·vue.js
web150854159351 小时前
vue 集成 webrtc-streamer 播放视频流 - 解决阿里云内外网访问视频流问题
vue.js·阿里云·webrtc
一个处女座的程序猿O(∩_∩)O4 小时前
vue3 如何使用 mounted
前端·javascript·vue.js
迷糊的『迷』4 小时前
vue-axios+springboot实现文件流下载
vue.js·spring boot
web135085886354 小时前
uniapp小程序使用webview 嵌套 vue 项目
vue.js·小程序·uni-app
陈大爷(有低保)4 小时前
uniapp小案例---趣味打字坤
前端·javascript·vue.js
cronaldo915 小时前
研发效能DevOps: Vite 使用 Element Plus
vue.js·vue·devops
百罹鸟5 小时前
【vue高频面试题—场景篇】:实现一个实时更新的倒计时组件,如何确保倒计时在页面切换时能够正常暂停和恢复?
vue.js·后端·面试