[总结] - 京东H5活动开发脚手架

此框架主要用于开发京东移动端的运营活动页面

为什么要开发这个框架?

当然主要就是提高开发效率,目前我们可以通过通天塔平台,使用运营模式快速搭建活动,但是运营模式并不能满足各种特殊需求,而且越来越多需求通过自定义开发来实现。

如果使用自定义开发,即使一个简单的活动页,里面也可能涉及到很多业务逻辑,举个例子,当点击一个链接的时候需要判断当前在什么环境,如果是京东APP内,需要用原生的协议跳转,每个链接的跳转协议 也是不同,如首页,商详页,店铺页等等都是需要处理,非APP环境,微信手Q也是需要兼容、最后还有点击后需要提交埋点、还有一些优惠券、抽奖、京东提醒的功能要开发也是得看半天文档才能下手、所以我们要做的 就是把这些功能都整合到框架里面、开发者不用去管跟后端的交互。

我们想要一个怎么样的框架

一定是要简单容易上手,能满足平时的业务需求,所以VUE是比较好的选择,VUE的开发模式本身很适合单页应用,上手简单,即使没接触过的看下官方文档基本一天也能上手,还有就是组件式开发,方便后续模板积累和分享,为什么不用VUEX和REACT?,主要上手难度相对复杂,且运营活动本来就是简单的单页应用不需要用到状态管理。

目前做了哪些

目录结构

两个字简单

.
├─ dist         //打包后发布的目录
├─ src          //开发目录
    ├─ components
    │  ├─ base  //存放的是一些业务组件,比如单个商品、优惠券、加入购物车、秒杀组件等等
    │  └─ ui    //存放UI组件,如tab,吸顶导航、倒计时、Toast等
    ├─ css      //额外的css
    ├─ img      //额外的img
    ├─ js       //存放一些初始化JS和工具类js
    ├─ App.vue  //入口页面、页面代码从这里开始
    ├─ conf.js  //配置通天塔广告组商品组、页面分享信息等
    └─ main.js  // vue的初始化JS

拉取数据

运营活动一般都是需要拉取很多数据,所以我们希望能统一配置一次性拉取

conf.js里,我们现在拉一条广告组合商品组

advertIds: [{
    floor1: {
        id: '01274865',
        report: 'Babel,123_{advertId}_01110113'
    },
    
}],
productIds:[{
    hotSale: {
        id: '03019457'
    }
}]

拉广告组在advertIds里配置,商品组在productIds里配置

floor1 为广告组的对象名,自己命名,注意如果拉多条数据命名不要相同,名称相同只会返回一条

id 广告组id(广告组是从通天塔系统中配置)

report 埋点需要,可不填

如果要更复杂的查询需求可配置在composite里面,具体使用方法需要看这里

使用示例

// App.vue

<template>
    <div id="app">
        <div v-if="data.loaded">
            {{data.advs.floor1}}
            {{data.products.hotSale}}
        </div>
    </div>
</template>

<script>
export default{
    data(){
        return {
            data:this.$root.data
        }
    }
}
</script>

拉取后的数据是保存在data.advs,data.products内,由于拉取数据是异步的,确保所有数据拉取完毕再显示,加上判断data.loaded

跳转和发送埋点

给标签(可以是div,span)添加jump属性,jump值按特定的规则填写,用|分隔,看下面示例代码

//商品详情页
<a jump="item|skuid|eventId,param"></a>
//店铺页
<a jump="shop|shopId|eventId,param"></a>
//广告位
<a jump="adv|url|type|eventId,param"></a>
//首页
<a jump="home|eventId,param"></a>
//去登录页
<a jump="login|eventId,param"></a>
//优惠券中心
<a jump="couponCenter|eventId,param"></a>
//不跳转只发送埋点
<a jump="eventId,param"></a>
···

业务组件

一般需要跟数据交互的组件会归类为业务组件,如一条广告组数据,一条商品组数据,加入购物车按钮,优惠券等。

商品组件示例(单条商品)

//App.vue
<template>
    <ul>
        <li v-for="(item,index) in data.list">
            <Product
                :item="item"
                :index="index"
                :report="data.report"
                :fields="['tag','mkPrice']"
            >
            //其它自定义
            ...
            
            </Product>
        </li>
    </ul>
</template>
<script>
export default{
    data(){
        return {
            //hotSale在前面conf里配置获取的数据
            data:this.$root.data.product.hotSale
        }
    }
}
</script>
//...其它省略

  

Product是单条数据,不是一个列表,所以循环还是需要自己写。

参数说明

  • item:一条商品组数据
  • index: 在列表中的顺序
  • report:埋点,例:'Babel_xxx_,aaa_{name}_{index}',{}内的变量是数据中的字段
  • fields 字段,商品组默认显示商品链接,商品名称,商品图片,京东价格,如果需要其它则添加你想要的字段,填写的字段名必须跟数据里的字段一致

建议安装官方调试工具(chrome插件)vue-devtools,可以方便查看所有字段

组件默认显示几个常用的字段,如果不想显示可以通过Style隐藏或者在fields里设置,

fields=['!link',    //链接
        '!name',    //商品名
        '!image',   //图片
        '!jdPrice'  //价格
        ]

当然如果你都不显示其实也没必要使用Product组件

其它自定义内容写在Product标签内,如:

<Product>
    <span>{{ item.tag }}</span>
    <a jump="shop|123|xx">去店铺</a>
    <AddCart></AddCart>
</Product>

UI组件

优先找一些优秀的第三方组件,如果满足不了需求则自己重写。

一个比较简单的弹窗组件,没有使用js,示例:

<template>
    <Modal v-if="show">
        <div solt="head">head</div>
        <div solt="body">
            body
            <a @click="$emit('close')" ></a>
        </div>
        
    </Modal>
</template>
<script>
    export default{
        data(){
            return{
                //控制显示隐藏
                show:true
            }
        }
    }
</script>

StickyNav

Tabs

Slide 推荐使用swiper

开始使用

# 克隆到你本地
$ git clone git@git.jd.com:element/h5app-vue-boilerplate.git {project}
# 进入目录
$ cd {project}
# 提交前更改你的git地址
$ git remote set-url {your git address}
# 安装依赖 建议使用jnpm
$ jnpm install
# 启动项目
$ npm start
# 打包
$ npm run build

由于某些依赖组件存放在京东NPM库中建议使用jnpm安装 jnpm

开发过程中的建议

从数据驱动界面的思路去开发,不同于JQ通过操作dom,熟悉后开发效率有明显的提高

尽量不要引入jQuery,zepto等库,因为本身是移动端开发,没有什么兼容性问题,原生API + ES6已经足够使用

在开发过程有什么问题请联系lijie8@jd.com

最后