简介

MSHOP SDK 为主题提供给开发者使用的功能库,适用于直接运行在店铺页面上的 JavaScript(如 【自定义代码】 插件)

SDK 组成

  1. SDKapiui 两类功能组成

  2. api 主要由:基础网络 io、商城标准接口、基础工具库 组成

  3. ui 提供主题各 ui 模块的调用接口

入口对象

由主题在全局挂载 SDK 的 入口对象,直接使用 mshopwindow.mshop 即可调用 SDK 功能

declare global {
    /** 商城SDK调用入口对象 */
    export namespace mshop {
        /** 当前库的版本号 */
        const version: string;
        /** 店铺信息 */
        const shopInfo: ShopInfo;
        /** IO功能 */
        const io: {
            /** http请求 */
            http: IHttp,
            /** http请求拦截器 */
            interceptor: IHttpInterceptor,
        };
        /** 全局事件处理器实例 */
        const events: GlobalEventEmitter;
        /** 先派发后注册的再次派发策略类型 */
        const eventEmitterEnsureTypes: typeof EventEmitterEnsureTypes;
        /** 事件处理器的实现类 */
        const EventEmitterType: typeof EventEmitter;
        /** 所有商城标准接口 */
        const api: APIs;
        /** 工具函数封装 */
        const tool: Tools;
        /** 拦截器实现类 */
        const interceptors: Interceptors;
        /** 标准结果定义 */
        const results: IResults;
        /** HTTP 错误类型 */
        const httpErrorFlags: typeof HttpErrorFlags;

        // ...其他模块

        /** ui模块 */
        namespace ui {
            /** 购物车模块ui接口 */
            const cart: ICart;
            /** 商品模块ui接口 */
            const product: IProduct;
            // ...其他UI模块

        }
    }
}

使用方法

为了开发时能有类型感知和智能提示,SDK 提供了对应的类型定义库:

npm i --save-dev @mshop/api-types @mshop/ui-cart-types

yarn add --dev @mshop/api-types @mshop/ui-cart-types

使用 mshop 即可拥有智能提示:

console.log(mshop.shopInfo)
/*
{
  // 是否在装修编辑器模式
  "designMode": false,
  // 是否在主题预览模式
  "previewMode": false,
}
*/

购物车模块

1. 购物车事件调用示例

// 注册全局的“单商品加购成功”事件
mshop.ui.cart.on(mshop.ui.cart.cartEventNames.ADD_TO_CART, (param: Readonly<AddToCartParamMergeCart>, resultCart: Readonly<RawCartType>) => {
  // TODO
});
// 注册全局的“批量加购成功”事件
mshop.ui.cart.on(mshop.ui.cart.cartEventNames.BATCH_ADD_TO_CART, (param: Readonly<BatchAddToCartParamMergeCart>, resultCart: Readonly<RawCartType>) => {
  // TODO
});

2. 加购和批量加购调用示例

// 调用主题的单商品加购api
mshop.ui.cart.addToCart({
  // 本次加购是否清理购物车的原有商品,默认为false
  clear: false,
  // 商品id
  product_id: 111,
  // 变种id
  variant_id: 110,
  // 加购数量
  quantity: 2,
  // 加购来源标识,用于统计识别
  addType: 'customcode_email',
  // 商品所属分类名列表,需要尽量提供,统计识别需要
  categoryNames: [],
  // 其他自定义属性
  properties: {},
  // 加购成功后是否展示购物车,默认为true,可以不传
  showCart: true,
  onAddToCartActivated: () => {
    // 这里表示加购动作完成,可以将按钮loading之类的状态取消
  },
}).then(ret => {
  if (ret.success === false) {
    // 加购操作失败了(被已知行为拒绝或中止)
    if (ret.failMessage) {
        // 如果有需要UI提示的消息,由主题完成,不需要调用再次提示(如果调用场景比较特殊,全局吐司提示不够友好,也可以自己补充)
    }
    return;
  }
  // 成功后可以拿到最新的购物车数据
  let cartData = ret.data;
}).catch((err: Error) => {
    // 异常逻辑处理
    console.error(err);
    // 建议继续外抛,让sentry收集到
    throw err;
});
// 调用主题的批量加购api
mshop.ui.cart.batchAddToCart({
  // 本次加购是否清理购物车的原有商品,默认为false
  clear: false,
  // 加购来源标识,用于统计识别
  addType: 'customcode_email',
  product: [
    {
      // 商品id
      product_id: 111,
      // 变种id
      variant_id: 110,
      // 加购数量
      quantity: 2,
      // 商品所属分类名列表,需要尽量提供,统计识别需要
      categoryNames: [],
    }
  ],
  // 加购成功后是否展示购物车,默认为true,可以不传
  showCart: true,
  onAddToCartActivated: () => {
    // 这里表示加购动作完成,可以将按钮loading之类的状态取消
  },
}).then(ret => {
  if (ret.success === false) {
    // 加购操作失败了(被已知行为拒绝或中止)
    if (ret.failMessage) {
        // 如果有需要UI提示的消息,由主题完成,不需要调用再次提示(如果调用场景比较特殊,全局吐司提示不够友好,也可以自己补充)
    }
    return;
  }
  // 成功后可以拿到最新的购物车数据
  let cartData = ret.data;
}).catch((err: Error) => {
    // 异常逻辑处理
    console.error(err);
    // 建议继续外抛,让sentry收集到
    throw err;
});

3. 加购拦截器调用示例

// 拦截加购行为
mshop.ui.cart.interceptAddToCart(async (ev) => {
  // 可直接修改ev.params里的字段
  ev.params.addType = 'test';
  // 注意:如果想加上自己的自定义属性,需要使用拓展的方式,避免把其他的功能加的自定义属性覆盖
  ev.params.properties = Object.assign(e.params.properties ?? {}, { a: 1 });
  return;// 修改后直接返回

  // 也可以替换整个参数(一般不需要用到)
  return {
      newParams: ev.params
  };

  // 如果要中断操作:
  return {
      isAbort: true,
      abortMessage: '中止操作并传递中止原因,模块会根据场景进行显示或忽略,不传则不做任何提示',
  };
  
  // 如果要中断操作,但不需要主题的提示UI(比如做加购前表单填写,自己做了表单的聚焦和提示等场景):
  return {
      isAbort: true,
  };
})
// 拦截批量加购行为
mshop.ui.cart.interceptBatchAddToCart(async (ev) => {
  // 可直接修改ev.params里的字段
  ev.params.addType = 'test';
  // 注意:如果想加上自己的自定义属性,需要使用拓展的方式,避免把其他的功能加的自定义属性覆盖
  ev.params.properties = Object.assign(e.params.properties ?? {}, { a: 1 });
  return;// 修改后直接返回
  
  // 也可以替换整个参数(一般不需要用到)
  return {
      newParams: ev.params
  };

  // 如果要中断操作:
  return {
      isAbort: true,
      abortMessage: '中止操作并传递中止原因,模块会根据场景进行显示或忽略,不传则不做任何提示',
  };
  
  // 如果要中断操作,但不需要主题的提示UI(比如做加购前表单填写,自己做了表单的聚焦和提示等场景):
  return {
      isAbort: true,
  };
})

商品模块

1. 详情页获取商品信息用例以及监听商品sku变化

// 获取商品详情页信息(其他页面将返回undefined)
const product =  mshop.ui.product.getProductPageInfo()

//注册商品详情页sku变化
mshop.ui.product.getProductPageInfo().onVariantChange((currentVariantAttrs, currentVariant) => {
  /**
   *  currentVariant.buyAble 表示当前变种是否可购买 (false为规格未匹配到变种,或匹配到变种但无库存)
   */ 
  console.log(currentVariantAttrs, currentVariant)
})

商城标准接口

(店铺页面嵌入的js,不建议直接调用标准接口)

购物车api调用示例

await mshop.api.cart.addToCart({
    clear: true,
    product_id: productId,
    variant_id: variantId,
    quantity: quantity,
}).then(ret => {
    if (!ret.success) {
        // 加购api失败了(被已知行为拒绝或中止)
        if (ret.failMessage) {
            // 有提供友好显示消息,可以吐司提示   
        }
        return;
    }
    // 成功后可以拿到最新的购物车数据
    let cartData = ret.data;
}).catch((err: HttpError<any>) => {
    // 异常的话可以拿到包含请求详细信息的HttpError异常对象,建议继续抛出
    throw err;
});

Last updated