全局共享数据定义

MIP 提供 SPA 的整站沉浸式的体验,如果要打造复杂的业务场景,页面间数据共享是常见的需求。

比如这么一个场景: 在某电商平台的购物流程中,准备结算时进入订单确认页,需要新增收货地址。这时候点击跳转到新增收货地址页面,对收货地址列表(假设为addressList)进行了一些增删改的操作。当收货地址处理完成,再次返回到订单确认页时,确认页需要读取 addressList的内容并加入到订单信息中,那么这时候的addressList就是一个订单确认页与新增收货地址页这两个页面间需要共享的数据。

下面我们来介绍如何通过使用 <mip-data> 组件和 MIP.setData 方法来设置、使用和修改共享数据。

相关概念

在讲解如何设置和使用共享数据之前,我们首先来明确一些概念,以方便开发者在阅读后续提供的例子的过程中能有清晰的认知。

  1. 站的概念:

    首次访问 MIP 页面 A.html 后,后续通过一定规则打开的其他 MIP 页面(假设为 B.html、C.html 等)都能读取和使用到 A 页面设置的共享数据,同时,B、C 页面也能够持续地更新和新增共享数据。A、B、C 页面同属一个站点

  2. 页面数据:只有当前页面可以访问和使用
  3. 共享数据:站内多页面可用
  4. 页面可用数据/全局数据:页面数据 + 共享数据

下面将以递进的方式提供例子,每一步都以前一步的输出为输入,请留意。

设置共享数据

用 # 标识共享数据

在数据字段前添加 # 标识为共享数据(仅检测数据第一层),否则仅为页面数据。

如:

1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- A.html --> <mip-data> <script type="application/json"> { "#global": 1, "#global2": 2, "test": { "#info": 3 }, "name": "a" } </script> </mip-data>

此时 A 页面可用的数据源为

1
2
3
4
5
6
7
8
{ "global": 1, "global2": 2, "test": { "#info": 3 }, "name": "a" }

此时共享数据源为:

1
2
3
4
{ "global": 1, "global2": 2 }

共享数据将在站内每个页面(A、B、C)都能被读取和使用(前提是定义了共享数据的页面已被访问)

数据继承

使用数据时,优先从页面数据源中查找,当在页面数据源中不存在时,MIP 将再向上查找共享数据源。

当 A 页打开 B 页时,B 页数据设置情况如:

1
2
3
4
5
6
7
8
9
<!-- b.html --> <mip-data> <script type="application/json"> { "name": "b", "age": 1 } </script> </mip-data>

此时 B 页面可用的数据源为

1
2
3
4
5
6
{ "global": 1, "global2": 2, "name": "b", "age": 1 }

此时共享数据源为:

1
2
3
4
{ "global": 1, "global2": 2 }

数据冲突

当新打开页面所设置的数据存在与现有共享数据重名的字段时,区分以下情况:

  1. 数据没有 # 标识,即仅为页面数据,将保存为页面数据,不影响共享数据(下面例子中的 global2 ),后续有对该数据的读取和修改操作,将只处理页面数据;

  2. 数据带有 # 标识,将提升为共享数据,覆盖原共享数据中同样字段的数据,并同时影响其他使用了该共享数据的页面(下面例子中的 global )

当打开 C 页时,C 页面数据设置情况如:

1
2
3
4
5
6
7
8
9
10
<!-- c.html --> <mip-data> <script type="application/json"> { "#global": 3, "global2": 2333, "name": "c" } </script> </mip-data>

此时 C 页面可用的数据源为

1
2
3
4
5
{ "global": 3, "global2": 2333, "name": "c" }

此时共享数据源为:

1
2
3
4
{ "global": 3, "global2": 2 }

修改共享数据

调用 MIP.setData 方法修改数据时,区分以下几种情况:

显式指定

如果指定必须修改共享数据,则需要开发者在数据前添加 # 标识显式指定

如果不显式指定需要修改共享数据,当需要修改的数据字段既存在于共享数据又存在于页面数据时,MIP 会自动判别为需要修改页面数据,而非共享数据。

显式指定后,如在 C 页面调用 MIP.setData({'#global2': 4})

此时 C 页面可用的数据源为

1
2
3
4
5
{ "global": 3, "global2": 2333, "name": "c" }

此时共享数据源为( global2 已被修改):

1
2
3
4
{ "global": 3, "global2": 4 }

MIP 自动判断

没有显式指定的情况下,MIP 会自行判断该数据是共享数据还是当前页面的数据,该修改哪个数据源;

  1. 如果要修改的数据字段既存在于共享数据源也存在于页面数据源,将只修改页面的数据源

    如:在 C 页面调用 MIP.setData({'global2': 2444})

    此时 C 页面可用的数据源为

    1
    2
    3
    4
    5
    { "global": 3, "global2": 2444, "name": "c" }

    此时共享数据源不变(因 global2 对 C 页面而言是页面数据,修改不影响共享数据),为:

    1
    2
    3
    4
    { "global": 3, "global2": 4 }
  2. 如果要修改的数据字段仅为页面数据,将不影响共享数据

    如:在 C 页面调用 MIP.setData({'name': 'name-c'})

    此时 C 页面可用的数据源为

    1
    2
    3
    4
    5
    { "global": 3, "global2": 2444, "name": "new-c" }

    此时共享数据源不变(同样的,修改的是 c 页面的页面数据)

  3. 如果要修改的数据字段为共享数据,将直接修改共享数据

    如:在 C 页面调用 MIP.setData({'global': '5'})

    此时 C 页面可用的数据源为

    1
    2
    3
    4
    5
    { "global": 5, "global2": 2444, "name": "new-c" }

    此时共享数据源为:

    1
    2
    3
    4
    { "global": 5, "global2": 4 }

使用共享数据

使用共享数据与使用普通页面数据并无不同,开发者可以继续使用 mip-bind 章节中所介绍的 m-bind/m-text 指令来绑定和使用数据。共享数据与页面数据不同之处在于设置和修改的时候,相信经过讲解开发者已经对此有所了解。