Technical Case Study of JD Smart Procurement App: Frontend Architecture, Component Library, Build Tools, and Optimization
This article presents a comprehensive technical case study of the JD Smart Procurement mobile app, detailing its front‑end architecture based on Vue, the use of the NutUI component library, TypeScript integration, request handling with Axios, build tooling with Gaea, multi‑page Webpack configuration, performance optimizations, and solutions to various development challenges.
The JD Smart Procurement App is an enterprise‑focused mobile procurement platform built on JD's mobile technology, aiming to digitize procurement across multiple industries such as finance, telecom, transportation, energy, and more.
Two major procurement pain points are addressed: mobile‑centric purchasing and employee‑benefit/channel‑reward distribution, both solved through a collaborative online procurement workflow.
Front‑end Architecture
The project adopts Vue as the core framework and utilizes JD's internally developed mobile component library NutUI (2.0+). Key components highlighted include:
Address – a four‑level address selector used in shopping‑type flows.
Dialog – supports both tag‑style and function‑style usage. Example usage:
this.$dialog({
title: "是否确定提交",
content: "采购人将第一时间看到您的提报,在下单之前可撤回重新修改"
}); <nut-dialog title="清单Excel将发送至以下邮箱">
<input type="text" placeholder="请输入邮箱地址" class="inputemail"/>
</nut-dialog>Function‑style dialog with HTML content:
_this.$dialog({
title: "清单Excel将发送至以下邮箱",
content: "<input type=\"text\" placeholder=\"请输入邮箱地址\" class=\"inputemail\"/>"
});Retrieving the input value (currently using DOM query):
let email = (document.querySelector('.inputemail') as any).valueStepper – a numeric stepper component used in cart pages, with methods such as add, reduce, change, focus, blur.
TypeScript Integration
The project combines Vue, Vuex, and TypeScript. Vue‑property‑decorator is used for class‑style components:
import { Vue, Component, Prop } from 'vue-property-decorator'
@Component({
components: {}
})
export default class ReportItem extends Vue {
@Prop({ type: Object, required: true, default: {} }) itemData!: object
}Vuex is typed via the vuex‑class helper:
import { createDecorator } from 'vue-class-component';
import { mapState, mapGetters, mapActions, mapMutations } from 'vuex';
export var State = createBindingHelper('computed', mapState);
// ... helper implementation ... import { State, Mutation } from 'vuex-class'
export default class ReportList extends Vue {
@State scrollTop
@Mutation saveTop
}Network Request Layer
Axios is the preferred HTTP client. A typed request wrapper is defined:
export interface ReqOptions {
uri?: string;
query?: object | null;
data?: { [key: string]: any };
}
export interface ResOptions {
code: number | string;
message: string;
data: { [key: string]: any };
} class Request {
static instance: Request;
request: AxiosInstance;
cancel: Canceler | null;
methods = ['get', 'post'];
curPath: string = '';
constructor(options: AxiosRequestConfig) {
this.request = axios.create(options);
this.cancel = null;
this.curPath = options.baseURL || '';
this.methods.forEach(method => {
this[method] = (params: ReqOptions) => this.getRequest(method, params);
});
this.initInterceptors();
}
// ... initInterceptors, getRequest, getInstance ...
} export let api = Request.getInstance();
const res = await this.$api.get({ uri: reportTab });Global Vue typings are extended in shime-global.d.ts to expose $api , $router , etc.
Performance Optimizations
Lazy‑load images using a custom directive or the vue-lazyload plugin.
Skeleton screens for page placeholders before data loads.
Gaea build tool (Node.js + Webpack) with Happypack, progress‑bar, and notifier plugins to speed up builds.
Code splitting via dynamic import() for route‑level components.
Multi‑page Webpack configuration with separate entry points and html-webpack-plugin instances.
Keep‑alive with scroll position caching to preserve list scroll state.
Global navigation guard to toggle keepAlive per route.
iOS low‑version keyboard handling by listening to focusout and resetting scroll.
Header gradient effect on scroll, later simplified to a solid color change after a threshold.
Conclusion
The article demonstrates a full‑stack front‑end solution for a mobile procurement system, covering component reuse, TypeScript safety, request abstraction, build efficiency, and UI/UX refinements, while sharing practical lessons learned throughout the development process.
JD Retail Technology
Official platform of JD Retail Technology, delivering insightful R&D news and a deep look into the lives and work of technologists.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.