林昶
林昶
Published on 2025-12-04 / 146 Visits
3
0

移动端底座二开流程

前言

  • 在移动端的功能开发时,会沉淀很多通用的行业包标准功能。在实际的项目交付时,会经常出现同一个功能,但复制了多份源码,导致【标准版本】和【交付版本】很难实现代码同步,代码维护困难。

  • 移动端底座的核心功能就是实现同一个功能只保留一份源码。同时,可以动态组合业务功能的【标准版本】支撑项目交付,也可以增量添加项目交付时的【定制化功能】

移动端底座架构设计

移动端底座架构设计

移动端底座构建流程

移动端底座构建流程

一、环境准备

1.1 基础环境

  1. node环境安装

  • node.js

具体配置请参照文档:本地部署运行-node

  • npm

具体配置请参照文档:本地部署运行-npm

  • yarn

具体配置请参照文档:本地部署运行-yarn

1.2 开发环境

  1. 本地hosts配置

具体配置请参照文档:系统快速上手-配置本地 hosts

  1. npm配置

具体配置请参照文档:系统快速上手-npm 配置准备工作

  1. sie-cli脚手架安装

 全局安装 sie-cli 脚手架
npm install -g sie-cli
 查看 sie-cli 版本,确认安装成功,使用大写 -V
sie-cli -V

sie-cli 脚手架安装

二、业务包开发

提示

内部开发使用现有的gitLab项目,已经创建好了移动端底座,无需再手动创建,可以跳过步骤2.1步骤2.2

  • 标品项目,主要包含【LED】【标品SMT】【标准行业包功能PUBLIC】【标准工治具功能TOOL】:

    • GIT地址:http://192.168.175.208/dme/mbm-mom-app-ui.git

    • 项目名:mbm-mom-app-ui

    • 分支名:dev

  • 定制化项目,主要包含【国星SMT

    • GIT地址:http://192.168.175.208/ns-odc/mbm-mom-nationstar-app.git

    • 项目名:mbm-mom-nationstar-app

    • 分支名:dev-package

2.1 appCode 生成

  1. 打开管理系统中的业务包管理页面,页面路径是【DEVOPS-移动端管理-业务包管理】,我们要操作的内容位于“业务包管理”面板。

  2. 业务包管理面板中的业务包名称由一级菜单和二级菜单构成,例如:《锡膏管理》下包含了“回温”、“粘度测试”、“锡膏查询”、“搅拌”、“报废”、“冷藏” 6 个功能页面。

    • 假设我们现在挑选了“回温”、“搅拌”,“开封”、“密封”作为我们新项目里已有的功能,在对应的位置勾选上,然后点击“生成 AppCode” 按钮,会出现一个确认的弹窗。

    • 点击“确认”按钮后,需要填写相关信息来生成 AppCode。

      应用名称:前端团队在 DCloud 官网创建的可选应用列表,选择你认为合适的一个;

      描述:备注;

    • 点击“保存”按钮,apk 会生成一个唯一的 appCode,点击“复制”按钮,留待后续生成二开底座或者 apk 时使用,至此动态组合业务包生成 appCode 完成。

2.2 创建移动端开发底座

  1. 回顾上一个步骤(动态组合业务包生成 appCode),如果你记得复制 appCode 的话,appCode 已经存在于你的剪切板中。不记得也没有关系,可以去【DEVOPS-移动端管理-业务包管理】标签页,点击“生成 apk”按钮,会打开一个弹窗,里面有一个选项是“从历史记录生成”。

    img

    打开选项,你会看见很多已经存在的 appCode,这时候你要发挥你的记忆力,找到对应的标题,可以逆推出你所需要的 appCode。

    img

  2. 选择一个空白的文件夹打开命令行程序(以 Windows 操作系统为例,使用 cmd.exe 进行命令输入操作)

     创建移动端开发底座
    sie-cli init
    

    当命令开始执行后,会有部分配置提供选择,例如:

    • 项目模板

    • 项目名称(项目名)

    • appCode(在此处粘贴上你上一步复制的 appCode)

    • 站点信息(通俗理解为服务器 ip 地址)

    回车之后,脚手架会自动拉取基座内容,等待安装结束。

    img

    成功标志!

    底座目录结构
    demo-app
     ├─public
     ├─src
     │  ├─api
     │  │  └─modules
     │  ├─config
     │  ├─const
     │  ├─pages
     │  │  ├─public
     │  │  │  ├─msd-material-operate-opening
     │  │  │  └─msd-material-operate-sealing
     │  │  └─smt
     │  │      ├─solder-paste-mixing
     │  │      └─solder-paste-warming
     │  ├─static
     │  │  ├─img
     │  │  └─style
     │  ├─store
     │  │  └─modules
     │  ├─utils
     │  └─views
     │      ├─demo
     │      ├─index
     │      │  └─components
     │      ├─systemLog
     │      └─user
     │          └─api
     └─unpackage
         └─res
             └─icons
    

2.3 业务包创建与开发

2.3.1 创建业务包

 进入基座所在文件夹
cd demo-app

 执行脚手架的创建业务包命令
sie-cli createPage

 以“MSD管理”下的“品质确认”作为例子
 产品线:public
 包名:msd-quality-confirm
 分组名称:MSD管理
 分组编码:msd-management
 菜单名称:品质确认
 版本:0.0.1
 描述:msd-品质确认

提示

  • 可以直接把产品线当作文件夹,比如国星的客开项目,产品线一般直接填写nationstar即可

  • 分组编码分组名称填写时请从MBM栏目管理中查找,如果没有对应的分组,请提前创建

当命令开始执行后,会有部分配置需要填写,例如:

  • 产品线:同一产品归类在一个文件夹下;

  • 业务包名称:烤串语法,输入后回车会立刻创建对应的文件夹;

  • 分组名称:可以理解为一级菜单名称,必填;

  • 分组编码:可以理解为一级菜单的编码,必填;

  • 菜单名称:必填;

  • 版本:格式为【Major(主版本号).Minor(次版本号).Patch(修订版本号)】;

  • 描述:package.json 里的 description;

  • 关键词:package.json 里的 keywords;

  • 作者:package.json 里的 author;

img

创建了功能页后的目录结构,可以看出`public`下增加了`msd-quality-confirm`文件夹

demo-app
├─public
├─src
│  ├─api
│  │  └─modules
│  ├─config
│  ├─const
│  ├─pages
│  │  ├─public
│  │  │  ├─msd-material-operate-opening
│  │  │  ├─msd-material-operate-sealing
│  │  │  └─msd-quality-confirm
│  │  │      └─api
│  │  └─smt
│  │      ├─solder-paste-mixing
│  │      └─solder-paste-warming
│  ├─static
│  │  ├─img
│  │  └─style
│  ├─store
│  │  └─modules
│  ├─utils
│  └─views
│      ├─demo
│      ├─index
│      │  └─components
│      ├─systemLog
│      └─user
│          └─api
└─unpackage
    └─res
        └─icons

2.3.2 业务包开发

 进入品质确认的文件夹
cd src\pages\public\msd-quality-confirm

 使用编辑器打开文件夹(建议使用vscode)
code .

开发“品质确认”需要以下几个文件。

  1. /api/index.js

    需要注意的地方:

    (1)使用基座进行开发时,用基座提供的请求接口

    (2)页面接口要加上备注,方便后续维护

import request from "@/api/index";
const basePath = "/smt/msd-material-app-operate";

/**
 * 取出干燥柜--检查物料信息
 * @param data
 * @returns {Promise}
 */
export const checkMaterialWhenTakeOut = data => {
  return request({
    url: `${basePath}/app/checkMaterialWhenTakeOut`,
    method: "GET",
    data
  });
};

/**
 * 品质确认
 * @param data
 * @returns {Promise}
 */
export const qualityConfirm = data => {
  return request({
    url: `${basePath}/app/qualityConfirm`,
    method: "GET",
    data
  });
};
  1. /components/usedRecord.vue

<template>
  <view class="used-record-item">
    <view>
      <view>
        <view class="half">
          <view class="label-value w-50">
            <view class="label">
              <text>物料条码</text>
            </view>
            <view class="value">
              <text>{{ data.barCode }}</text>
            </view>
          </view>
          <view class="label-value w-50">
            <view class="label">
              <text>编码</text>
            </view>
            <view class="value">
              <text>{{ data.materialCode }}</text>
            </view>
          </view>
        </view>

        <view class="half">
          <view class="label-value w-50">
            <view class="label">
              <text>名称</text>
            </view>
            <view class="value">
              <text>{{ data.materialName }}</text>
            </view>
          </view>
          <view class="label-value w-50">
            <view class="label">
              <text>数量</text>
            </view>
            <view class="value">
              <text>{{ data.qty }}</text>
            </view>
          </view>
        </view>

        <view class="half">
          <view class="label-value w-50">
            <view class="label">
              <text>暴露时长</text>
            </view>
            <view class="value">
              <text>{{ data.remainderExposureHour }}</text>
            </view>
          </view>
          <view class="label-value w-50">
            <view class="label">
              <text>剩余寿命</text>
            </view>
            <view class="value">
              <text>{{ data.residueExposureHour }}</text>
            </view>
          </view>
        </view>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  name: "used-record",
  props: {
    data: {
      type: Object,
      default: () => {}
    }
  },
  computed: {},
  methods: {}
};
</script>

<style lang="scss" scoped>
@import "../../../../uni.scss";

.used-record-item {
  border: 1px solid $uni-border-color;
  padding: 0 20rpx;
  margin: 10rpx 0;
  font-size: 28rpx;
  .u-row {
    margin: $uni-spacing-col-sm 0;
  }
  .label {
    width: 130rpx;
  }
  .half {
    display: flex;
    .w-50 {
      flex: 2;
      width: 0;
    }
  }
}
</style>
  1. /index.vue

<template>
  <view class="station-pass-collection-index">
    <view>
      <u-sticky class="sticky">
        <view class="scan-bar">
          <app-scan-bar
            placeholder="请扫描物料条码"
            v-model="barCode"
            :focus="inputFocus"
            @blur="handleBlur"
            @search="handleSearch"
            @scan="handleSearch"></app-scan-bar>
        </view>
      </u-sticky>
    </view>

    <view>
      <view>
        <view class="header">
          <view class="title">扫描明细</view>
          <view class="title">记录 {{ recordSize }}</view>
          <view class="title" style="margin-right: 20px">数量 {{ totalQty }}</view>
        </view>
      </view>
      <view class="list">
        <usedRecord v-for="(item, index) in usedRecordList" :key="index" :data="item" />
      </view>
    </view>

    <view class="bottom-fixed">
      <view>
        <u-button type="primary" text="重置" @click="reset"></u-button>
      </view>
    </view>
  </view>
</template>

<script>
import { qualityConfirm } from "./api/index";
import { $toast } from "@dme/uni-toast";
import usedRecord from "./components/usedRecord.vue";
import appScanBar from "@dme/app-scan-bar";

export default {
  name: "user",
  components: {
    usedRecord,
    appScanBar
  },
  data() {
    return {
      usedRecordList: [],
      inputFocus: true,
      isShow: true,
      barCode: "",
      recordSize: 0,
      totalQty: 0
    };
  },

  methods: {
    reset() {
      this.recordSize = 0;
      this.totalQty = 0;
      this.usedRecordList = [];
      this.barCode = "";
      this.inputFocus = true;
    },
    handleBlur() {
      this.inputFocus = false;
    },
    async handleSearch(v) {
      this.barCode = v;
      if (this.barCode == "") {
        $toast(`请先扫描产品标签`);
        return;
      }
      try {
        const res = await qualityConfirm({
          barcode: this.barCode
        });
        console.log("res :>> ", res);
        if (res.code == "0") {
          this.recordSize++;
          this.totalQty = this.totalQty + res.data.qty;
          this.usedRecordList.unshift({
            barCode: this.barCode,
            materialCode: res.data.materialCode,
            materialName: res.data.materialName,
            qty: res.data.qty,
            remainderExposureHour: res.data.remainderExposureHour,
            residueExposureHour: res.data.residueExposureHour
          });
        } else {
          $toast(res.msg);
        }
      } catch (err) {
        console.error("品质确认失败");
      }
      this.barCode = "";
      this.inputFocus = true;
    }
  },
  onNavigationBarButtonTap() {
    $toast("点击了右上角按钮");
  }
};
</script>

<style lang="scss" scoped>
@import "../../../uni.scss";

.station-pass-collection-index {
  $padding-width: $uni-spacing-col-base;
  $margin-width: $uni-spacing-col-base;
  .sticky {
    background-color: fff !important;
    .scan-bar {
      width: 100%;
      margin: $margin-width 0;
    }
    .title {
      color: $uni-color-primary;
      margin-top: $margin-width;
      padding: 0 $padding-width;
    }
  }
  .header {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    margin-left: 20px;
  }
  .bottom-fixed {
    position: fixed;
    right: 0;
    bottom: 0;
  }
}
</style>
<!-- TODO:等文档补全后,将这里替换具体的组件文档 -->

为了方便开发,前端团队创建了一些基础库给大家使用,分别是:

  • 接口开发用:@dme/template-app-utils-request

  • 消息弹窗: @dme/uni-toast

  • 扫码框组件:@dme/app-scan-bar

  • 底部选择组件:@dme/app-bottom-picker

  • 右侧打开侧边栏列表组件:@dme/app-cell-vue

  • 图片组件:@dme/app-image-vue

等等等等...

在 demo-app/src/package.json 可以找到这些基础库

"dependencies": {
    "@dme/app-bottom-picker": "^0.0.0-4",
    "@dme/app-cell-vue": "^0.0.0-6",
    "@dme/app-image-vue": "^0.0.0-6",
    "@dme/app-list-vue": "^1.0.0-0",
    "@dme/app-nav-bar": "^0.0.0-5",
    "@dme/app-picker-vue": "^0.0.1-10",
    "@dme/app-popup-picker": "^0.0.0-11",
    "@dme/app-scan-bar": "^0.0.0-11",
    "@dme/app-slide2del": "^0.0.0-4",
    "@dme/app-table-vue": "^0.0.0-8",
    "@dme/app-upload-dme": "^1.0.0-0",
    "@dme/datetime": "^0.0.0-6",
    "@dme/style-app": "^0.0.1-0",
    "@dme/template-app-style-global": "^0.0.0-6",
    "@dme/template-app-utils-loading": "^0.0.0-1",
    "@dme/template-app-utils-request": "^0.0.0-5",
    "@dme/uni-clog": "^0.0.0-3",
    "@dme/uni-modal": "^0.0.0-1",
    "@dme/uni-toast": "^0.0.0-1",
    "@dme/utils-form": "^0.0.0-1",
    "@dme/utils": "^0.0.1-1",
    "@dme/utils-app": "^0.0.3",
}

2.3.3 详情页开发

如果业务包有详情页,需要额外手动创建详情页,主要有三个步骤:

  1. 在【业务包】根目录,新建详情页文件,命名规则不做限制,参考命名为indexNext.vue或者detail.vue

创建详情页

  1. 在【业务包】根目录,修改配置文件package.json,以indexNext.vue为例,确保exportPathexports的信息匹配

修改配置文件

  1. 完成这前步后,其实已经完成了业务包开发,但是为了本地开发调试方便,需要在pages.json页面给新建的详情页添加路由,需要保证path字段的值是一致的。并且需要特别注意,pages.jsonpath首部会少一个/

添加详情页路由

2.4 项目运行验证

  1. 依赖安装

回到项目根目录,执行依赖安装命令,如果有疑问请仔细阅读项目根目录的README.md

 cd 到项目根目录中
npm run ins:all

img

  1. 项目运行

npm run dev

img

三、业务包发布

3.1 业务包打包

业务包开发完成后,进入【业务包】根目录,执行打包命令。

提示

举个例子,过站采集的业务包根目录为:src\pages\public\station-pass-collection 可以通过检查对应的目录是否有package.json文件,来判断当前目录是否有问题

cd src\pages\public\station-pass-collection
 执行打包命令,对应修订版本号更新
npm run pack:z

 根据实际需要也可以执行以下命令
 npm run pack:x   对应主版本号更新
 npm run pack:y   对应次版本号更新

业务包打包命令

如下图,业务包根目录出现*.tgz文件的时候证明打包成功了

业务包打包结果

3.2 业务包发布

  1. 上传业务包

上传业务包

  1. 业务包默认信息

业务包有四项主要的默认信息,分别是功能菜单编码功能菜单名称分组名称分组编码

  1. 功能菜单编码:业务包的唯一ID,不可变

  1. 功能菜单名称:可变,数据ID是功能菜单编码

  1. 分组名称:可变,数据ID是功能菜单编码

  1. 分组编码:可变,数据ID是功能菜单编码

上传业务包

  1. 业务包信息变更

MBM系统的栏目管理菜单中,可以基于功能菜单编码,对其他三项数据进行修改

提示

针对其他三项数据的修改只做覆盖,一旦删除栏目管理对应的值后,业务包依旧会使用默认信息

  • 修改前MBM系统栏目管理如图

上传业务包

  • 修改功能菜单名称

上传业务包

  • 修改分组名称分组编码

上传业务包

  • 修改后MBM系统栏目管理如图

上传业务包

  • 修改后DEV环境业务包管理如图

上传业务包

3.3 代码提交【切记!!】

确保业务包发布完成后,需要将本地代码提交到gitLab,同步业务包的版本信息,防止协同开发时版本冲突

提示

内部开发使用现有的gitLab项目

  • 标品项目,主要包含【LED】【标品SMT】【标准行业包功能PUBLIC】【标准工治具功能TOOL】:

    • GIT地址:http://192.168.175.208/dme/mbm-mom-app-ui.git

    • 项目名:mbm-mom-app-ui

    • 分支名:dev

  • 定制化项目,主要包含【国星SMT

    • GIT地址:http://192.168.175.208/ns-odc/mbm-mom-nationstar-app.git

    • 项目名:mbm-mom-nationstar-app

    • 分支名:dev-package

3.4 流水线运行

  1. 业务包管理菜单中,点击从历史选择业务包,选中其中一个历史记录,比如叫标品SMT【全部功能】,然后点击确定按钮

流水线运行

  1. 上次历史记录包含的所有业务包会自动反选到当前页面,确认勾选的业务包和对应的版本无误后,点击生成AppCode按钮,选择对应的应用名称和写入描述,比如叫标品SMT【全部功能】,最后点击保存按钮,复制生成的AppCode

流水线运行

流水线运行

  1. 找到对应的流水线,点击运行按钮后,输入获取到的AppCode,即可完成功能发布

提示

AppCode代表的是指定版本业务包的集合,可以同时使用于dev或者联建等任意环境

流水线运行

3.5 手动引入标品业务包

提示

手动引入业务包仅用于本地功能测试,并不影响APK打包

手动引入标品业务包主要参照以下前三个步骤:

  1. 业务包管理菜单中,勾选对应功能模块,点击生成AppCode按钮,任意选择一个应用和填写描述后,点击保存,并继续下一步,点击复制按钮复制生成的appCode

生成AppCode

  1. 任意选择一个demo的目录结构,执行项目生成命令,根据提示填写信息,并输入上一步获取的appCode,可以参照[2.2 创建移动端开发底座](2.2 创建移动端开发底座)

sie-cli init

创建移动端底座

  1. 打开生成的项目,将四部分(文件package.json、pages.json、menuList.json和文件夹pages)内容复制到目标项目中,即可实现将标品业务包引入到实施项目中,以国星实施项目为例:

  • 文件 package.json(注意此处的package.jsonsrc下的文件)

生成的demo项目:

生成的项目

修改后的国星实施项目:

修改后的国星实施项目

提示

  • npm包版本设置为latest意味着只会安装最新版本

  • npm包版本设置为^开头意味着主版本不变,但是次版本补丁版本可以匹配当前版本或者更高的任意版本,都符合要求,具体选择哪个版本根据依赖间的关系自行调整,只要不低于当前版本都是符合的

  • 文件 pages.json

生成的demo项目:

生成的项目

修改后的国星实施项目:

修改后的国星实施项目

提示

由于这里还包含了一个详情页,所以一共是3个页面,一定要注意

  • 文件 menuList.json

生成的demo项目:

生成的项目

修改后的国星实施项目:

修改后的国星实施项目

提示

  • 如果对应的菜单分组不存在,则复制整个大红框的所有内容

  • 如果对应的菜单分组已存在,则只需要复制小红框的功能菜单即可

  • 文件夹 pages

生成的demo项目:

生成的项目

修改后的国星实施项目:

修改后的国星实施项目

提示

  • 如果对应的public文件夹不存在,则复制整个文件夹

  • 如果对应的public文件夹已存在,则只需要复制其中的子文件夹即可

  1. 至此,手动引入标品业务包所有工作完成,安装依赖后运行查看效果

 进入 src 目录安装依赖
cd src
yarn install

 回到项目根目录运行项目
cd ..
npm run dev

四、APK 打包发布

4.1 APK 打包

  1. APK打包生成

  • 业务包管理菜单中,勾选对应功能模块,点击生成APK按钮

生成 APK

  • 勾选的所有功能会带到业务包的表格中,按顺序选择应用名称运行环境后,会自动带出推荐的下一个版本号,也可以手动修改。按要求填写发版内容,并按需填写备注后,即可点击保存按钮,点击后会触发APK自动生成的任务

生成 APK

提示

表单中从历史记录生成可以选择之前勾选的业务包记录,减少重复勾选业务包的工作

  1. APK生成结果

  • APP管理菜单中,可以看到上一步生成APK任务的生成状态

APK 生成结果

  1. APK生成日志查看

日志查看

4.2 APK 下载验证

  1. 下载生成的APK

APK 下载

  1. 在模拟器中验证APK功能

  • APK安装成功

APK 安装成功

  • 输入账号密码后登录

登录

  • 确认功能菜单是跟4.1-1勾选的业务包一致

确认功能菜单

  • 任意点击一个功能菜单,并测试功能是否正常

测试功能是否正常

4.3 APK 发布

功能确认无误后,在APP管理菜单中,找到对应的APK生成记录,选择更多,并点击发布按钮

APK 发布

确认发布状态

五、异常情况处理

5.1 APP 日志查看

  1. 登录页日志查看

连续点击6次登录页logo,可以打开日志,便于检查问题

日志查看

日志查看

  1. 菜单页日志查看

日志查看

日志查看

5.2 基于 HbuilderX 的模拟器调试

如果打包APK后问题较多,可以在本地生成一个项目,通过HbuilderX的模拟器调试,方便定位问题

  1. 获取指定的appCode

获取指定的 appCode

获取指定的 appCode

  1. 生成本地项目

任意选择一个demo的目录结构,执行项目生成命令,根据提示填写信息,并输入上一步获取的appCode

sie-cli init

生成本地项目

  1. 进入项目根目录,执行依赖安装命令

安装依赖

安装依赖

  1. 打开模拟器,获取ADB调试端口

获取 ADB 调试端口

获取 ADB 调试端口

  1. 使用HbuilderX的打开生成的项目,并配置模拟器调试端口

配置模拟器调试端口

配置模拟器调试端口

  1. 回到项目中,按步骤运行项目到模拟器中

  • 选择运行到Android App基座

运行到模拟器

  • 选中模拟器,并默认使用自定义基座,点击运行按钮

运行到模拟器

提示

如果HbuilderX无法检测到模拟器,可以尝试重启HbuilderX

无法检测到模拟器

  • 正常运行项目到模拟器中,并在控制台显示调试信息

输出调试信息到控制台

六、常见问题

6.1 代码报错

  1. 引用组件路径错误

提示

@符号一般代表目录src

  • 错误信息摘要Module not found: Error: Can't resolve '@/components/pickerVue/index.vue'

引用组件路径错误

  • 错误原因分析:在移动端底座中,所有的公共组件都剥离到组件库中,对应的目录架构src中不存在components文件夹,所以会报错,无法找到并解析对应的模块

  • 解决方案

    1. 【推荐】使用包引入方式,替代原来的引入方式,将import popupPicker from "@/components/popupPicker/index.vue";改成import popupPicker from "@dme/app-popup-picker";

改用包引入方式

  1. 【不建议】使用相对路径替代原来的引入方式,但需同时复制对应的组件到指定目录中【即业务包根目录】

改用相对路径引入方式

  1. 页面滚动条无法滚动

  • 错误信息摘要

  • 错误原因分析:在移动端底座中,为了适配多场景使用需求,将原来默认瀑布流的布局修改成为了flex布局

    • 瀑布流由于没有设置任何样式,所以天生自带滚动条

    • flex布局则是将整个页面进行了分块,每个块都可以单独做滚动

      • 好处就是可以适配更多场景

      • 坏处就是天生的滚动条是无效的,在需要滚动的区块处,需要手动添加滚动样式

  • 解决方案

    1. 【推荐】在最外层增加page-flex样式类,在需要使用的滚动的区块处,添加滚动的样式类cus-overflow-auto

页面滚动条无法滚动

  1. 【不建议】在最外层直接增加cus-overflow-auto样式类,其他不变,这种方式可以恢复成类似原来瀑布流的布局,虽然简单,但是相对没那么灵活

页面滚动条无法滚动

6.2 代码优化

  1. 标准的移动端组件库已全局引入,符合规则的组件可以直接使用,而无需单独声明

  • pages.json中已经统一注册了u-app-开头的两种格式的组件,意味这uview框架的组件和内部开发的移动端组件库都可以直接使用,减少代码量,改造如下图,将原有的组件<popupPicker />改成<app-popup-picker />,其他不变

全局引入标准的移动端组件库

  • 以上修改完成后,引入组件和注册组件的代码可以省略,下图红框中的代码可以删除

全局注册组件可以删除代码

提示

依此类推,其他u-app-开头的组件可以使用相同的方式优化

6.3 注意事项

  1. 在移动端底座中,onShowonNavigationBarButtonTap等生命周期需要通过新的方式使用

  • 可用的生命周期包含以下9个:onShowonReadyonHideonUnloadonPullDownRefreshonReachBottomonPageScrollonResizeonNavigationBarButtonTap

  • 使用时需要写入methods中,并在前面增加$符号

onShow

onNavigationBarButtonTap

  1. 在移动端底座中,不支持onLoad生命周期,需要获取页面跳转的option参数可以通过this.onLoadOption变量直接获取,数据跟option一致

onShow

  1. 定期更新全局的脚手架版本,更新命令npm install -g sie-cli,参照1.2 开发环境3. sie-cli 脚手架安装

  2. 业务包的编码是业务功能的唯一ID,请仔细查阅3.2 业务包发布

七、问答知识库

  1. 针对善治提到的问题如何快速定位BUG文件目录?

提示

  • 熟悉项目的可以直接找,如果找不到可以参照本案例

  • 通过这种方式找的原因是,业务包名称业务包分组有可能做了变更,不一定能直接找到,相关文档请参照3.2 业务包发布3. 业务包信息变更

  • 解决方案

    1. 【推荐】通过页面URL定位业务包功能

    • 第一步,确认功能名称,比如叫工治具维修

    工治具维修

    • 第二步,打开DEV环境,点击进入具体的业务包功能,查看具体的URL路径,比如/pages/tool/repair-execute/index,这个路径就是项目文件的所在路径

    工治具维修

    • 第三步,打开对应项目,根据第二步获取的路径找到对应的功能

    工治具维修

    1. 通过业务包的唯一ID定位业务包功能

    • 第一步,确认功能名称,比如叫工治具维修

    工治具维修

    • 第二步,在业务包管理中,查询工治具维修,并找到对应的包名@dme/app-tool-repair-execute

    工治具维修

    • 第三步,打开对应项目,并全局搜索@dme/app-tool-repair-execute

    工治具维修

提示

  • 以上,即可定位具体文件目录

  • 补充说明:

    • 由于本地开发中的业务包名称是写死的,而线上的是可以动态变更的,所以如果想找到本地代码中的业务包名称,可以在目录src\const\menuList.json中进行搜索

    • 搜索的信息是第二步中的编码字段tool-repair-execute-index,搜索结果中对应的title字段维修执行就是本地开发中看到的具体业务功能名称

工治具维修

  1. 如何根据旧的业务功能名称如何快速找到修改后对应的业务包名称

提示

本案例跟上一个案例是反过来的,上个案例是“新”找“旧”,这个案例是“旧”找“新”

  • 第一步,确认“原始”的功能名称,比如叫离线备料

  • 第二步,打开对应项目,在目录src\const\menuList.json中搜索离线备料, 搜索结果中对应的code字段smt-management-offline-material-preparation-index就是功能菜单的唯一编码,具体请仔细查阅3.2 业务包发布2. 业务包默认信息

离线备料

  • 第三步,在业务包管理中搜索smt-management-offline-material-preparation-index即可找到“翻新”的功能名称

离线备料

八、培训视频



Comment