wap2App 入门讲解,100%速成,全面为你讲解。

一、wap2App 是什么

wap2App 是一个将现有 M 站(也称手机 wap 站,区别于 pc 的 Web 站)快速发布成 App 的增强方案,通过 DCloud 的 wap2App 框架,进行简单的配置和必要的编程,即可完成 M 站的体验强化,达到原生应用的功能体验,进而再发布为原生安装包或流应用。

产品特点

  • 提供了原生渲染能力,让界面渲染速度和动画效果,达到原生体验(优化后的体验有多好,可以滚动到文档底部看 “案例体验” 章节)
  • 提供丰富的系统原生能力(定位、分享、支付、推送等),达到原生功能
  • 通过 JSON 配置页面规则和强化规则,工作量低,学习成本低
  • M 站仅需稍作修改,改造成本低
  • 强化部分和之前的 M 站解耦合,M 站后续升级业务逻辑,生成的 App 自动含有更新后的业务逻辑

生成文件目录结构如下:

  • sitemap.json:wap2App 核心配置文件,wap2App 的大部分工作在该文件中完成
  • app.js:为弥补 sitemap.json 的格式限制,提供的基于 JavaScript 的可编程增强方案
  • manifest.json:工程参数配置,比如 icon、splash 图等(打开该文件后有帮助链接)
  • client_index.html:内置静态页面,若首页有选项卡,需在该文件中配置
  • %APPID%.append.css:本示例中 APPID 为 “W2Am.example.com” ,故默认创建了一个 W2Am.example.com.append.css 文件;该 CSS 文件负责提前修饰首页的样式,比如隐藏 M 站首页的原生下载引导等 DOM 元素。
    以上文件的名称以及位置,不可修改或调整。

    二、sitemap.json 配置文件

    1. global

webviewParameter 设置标题栏

属性包含如下:

  • titleNView:原生导航栏样式配置
  • statusbar:系统状态栏样式配置
  • subNViews:NView 模板配置
  • pullToRefresh:下拉刷新配置
  • appendCss:向服务端页面插入的 CSS 代码
  • appendJs:向服务端页面插入的 JavaScript 代码
  • tabBar:选项卡切换效果优化,目前仅支持首页底部选项卡

easyConfig 为提升用户体验而提供的简化设置,比如后退处理

{
    "global": {
        //global 为全局配置,与 pages 数组中 webview 对象呈继承关系
        "webviewParameter": {
            "titleNView": {
                "autoBackButton": true,
                "backgroundColor": "#D74B28",// 导航栏背景色
                "titleColor": "#f7f7f7",// 标题颜色
                "titleSize": "17px",// 字体大小
                "splitLine": {// 标题栏的底部分割线,默认不显示底部分割线
                    "color": "#D74B28", // 分割线颜色
                    "height": "1px"
                }
            },
            "appendCss": ".download,.mui-bar-tab,header{display:none!important;} .mui-bar-nav~.mui-content,.info,.dcontent{padding-top: 0!important;} .sdcontent{top:0!important;}"
        },
        "easyConfig": {
            "quit": {// 参考文档 【http://ask.dcloud.net.cn/docs/#//ask.dcloud.net.cn/article/12750】 quit
                "toast": {
                    "showFeedback": false   // 默认为 true
                }
            }
        }
    }
}

2.pages 每个页面的单独设置

page 节点包含四个属性

  • webviewId:当前页面所属 webview 的 id,类型为 String,方便后续增强编程实现,比如在 app.js 中可使用 plus.webview.getWebviewById () 方法获取当前的 webview 对象
  • matchUrls:页面 URL 匹配规则,满足 matchUrls 匹配规则的页面,将使用当前页面配置规则打开,比如 webview 的 id 固定为本页配置的"webviewId"属性
  • webviewParameter webview 相关设置,比如原生导航条
  • easyConfig:为提升用户体验而提供的简化实现,比如 back 按键时,优先关闭弹出层

matchUrls 配置

matchUrls:页面链接匹配规则集合,类型为 Array,满足数组中任一项匹配条件,即可使用当前页面配置,故值域为 [matchurl1,matchurl2...]

选择匹配类型

  • href:页面完整 url,类型为 String,可选,与 window.location.href 进行比较
  • hostname 域名信息,类型为 String,可选,与 window.location.hostname 进行比较
  • pathname 路径信息,类型为 String,可选,与 window.location.pathname 进行比较
  • search 查询字符串,类型为 String,可选,与 window.location.search 进行比较
  • hash 锚点信息,类型为 String,可选,与 window.location.hash 进行比较

例子
http://ask.dcloud.net.cn/article/12731?canshu=123#maodian1

href="http://ask.dcloud.net.cn/article/12731"
hostname="ask.dcloud.net.cn"
pathname="/article/12731"
search="?canshu=123"
hash="#maodian1"

选择匹配值表达式

  • 默认为精确匹配,即字符串完全相等才匹配,如"/article/12731.html"
  • 正则匹配:以"REGEX:"为前缀,可简写为"R:",后跟正则字符串,如"REGEX:/\/article\/\d+.html$/ "
  • 通配符匹配:以"WILDCARD:"为前缀,可简写为"W:",后跟通配符,如 “WILDCARD:/article/*.html”

精确匹配模式

"pathname":"/login"

http://www.example.com/login   // 匹配成功
http://www.example.com/login/  // 匹配失败,pathname 为 '/login/',最后多了一个 '/'

正则匹配模式

  • ` /\/detail\/\d+.html$/ // 正则表达值字面量,/pattern/ 模式
  • new RegExp ("\/detail\/\d+\.html$") // 调用 RegExp 对象的构造函数

sitemap.json 是一个 JSON 格式的文件,不支持原生 JS

  • REGEX:"或"R:"开头的字符串
  • 通配符匹配模式 W:,"pathname": "W:/item/[0+]"

多条匹配规则同时设置的关系

{
        "hostname":"m.example.com"  // 匹配 hostname
        "pathname":"/"  // 匹配 pathname
    }

三、其他配置

1). 系统状态栏

系统状态栏位于手机屏幕顶端
wap2App-statusbar-01.png

属性包含如下:

  • style:状态栏前景色(文字颜色)
    • dark:深色前景色样式(即状态栏前景文字为黑色)
    • light:浅色前景色样式(即状态栏前景文字为白色)
  • background:状态栏背景色,默认应该和原生导航条背景色一致;
    • 在 wap2App 项目中,除首页外,其它页面默认均启用了原生导航条;因此,首页需要配置 background,其它页面,均无需配置。

background 首页未启用原生导航条

{
    "webviewId": "__W2A__m.example.com",// 首页
    "matchUrls": [
        //url 配置规则
    ],
    "webviewParameter": {
        "titleNView": false,// 首页默认不使用原生导航
        "statusbar": {
            // 状态条背景色,
            // 首页不使用原生导航条,颜色值建议和 global->webviewParameter->titleNView->backgroundColor 颜色值保持一致
            "background": "#f7f7f7"
        }
    }
}

2).配置导航栏

1.配置导航栏的样式

  • "backgroundColor": "#f7f7f7",// 导航栏背景色
  • "titleColor": "#000000",// 标题颜色
  • "titleSize": "17px"// 标题字体大小
  • "titleText": '我的项目',// 导航栏标题

2.单独设置某个页面导航栏样式

在 pages 下设置 webviewParameter,titleNView 重写即可

"pages": [
        {
            "webviewid":"detail",// 详情页
            "matchurls": [
                {
                    "pathname": "R:\\/detail\\/\\d+"
                }
            ],
            "webviewParameter": {
                "titleNView":{
                    "titleText":"新闻详情"  // 单独设置新闻详情页的标题内容
                }
            }
        }
    ]

3.导航条的启用 / 禁用

"titleNView": false 不使用原生导航条

2.完整的 titleNView 配置参数

手册

{
    "webviewId": "page1",
    "matchUrls": [
        //page1 url 匹配规则
    ],
    "webviewParameter": {
        "titleNView": {
            "titleText": "原生标题栏",
            "buttons": [
                {
                    "float": "right",
                    "fontSize": "27px",
                    "fontSrc": "__wap2app.ttf",//wap2App 内置字体文件
                    "text": "\ue602",
                    "onclick": "JavaScript:plus.webview.getWebviewById ('page1').evalJS ('myshare ();')"
                }
            ]
        }
    }
}

onclick 注意事项
总结一点,需要指定页面,调用函数,需要对应页面里面有这个函数

  1. 仅支持字符串类型,且以 JavaScript:为前缀
  2. 必须先获得对应的 webview,然后以 evalJS 的方式执行;evalJS 是 Webview 的标准 API,具体 API 参考 http://HTML5plus.org/doc/zh_cn/webview.html#plus.webview.WebviewObject,在里面搜 evalJS。
    evalJS 的意思就是让某个 Webview 运行其内部的某个 JS 函数。
    示例中,myshare () 这个函数写在 id 为 page1 的页面内,故需通过 plus.webview.getWebviewById ('page1') 获得目标 webview 对象,并且命令这个 Webview 运行 myshare 这个函数;
  3. 目标页面的函数必须是全局函数(通过 Windows 可访问的的函数);示例中调用的 myshare 方法,需要写在原生标题栏所属的 webview 页面中;
  4. 真机运行时,首页 webview 的 id 为"HBuilder",若为首页原生标题增加按钮,则建议使用 plus.webview.getLaunchWebview ().evalJS ('myshare ()');
  5. 注意在 onclick 后面的 JS 里,不能写 plus.webview.currentWebview ()。因为 sitemap 不运行在任何 Webview 下,在 sitemap 里写的 JS 其实是和 app.js 一起运行在一个独立的、不可见的本地 Webview 中。所以若需要操作当前 titleNView 所在的 Webview,也必须指定明确的 WebviewID。
  • 内置字体
     向右箭头:\ue600
    向左箭头(返回箭头):\ue601
    分享图标:\ue602
    收藏图标:\ue604
    主页图标:\ue605
    关闭图标:\ue650

通过 JS 动态调整 titleNView

`plus.webview.currentWebview ().setStyle ({titleNView: {titleText: 'new text'}});

首页启用原生导航条配置示例:

{
    "webviewId": "__W2A__m.example.com",// 首页
    "matchUrls": [
        //url 配置规则
    ],
    "webviewParameter": {
        "titleNView": {// 首页启用原生导航条
            "backgroundColor": "#FF00FF",// 导航栏背景色
            "titleColor": "#00ffff",// 标题颜色为白色
            "titleText": "wap2App 首页"
        },
        // 若首页启用了原生导航条,则建议将首页的 statusbar 配置为 false(或直接删除 statusbar 节点),这样状态条可以和原生导航条背景色保持一致;
        "statusbar": false

    }
}

3).subNViews 原生渲染区域,加快速度

而 Webview 则仍在慢慢经历:联网下载页面代码、构建 Dom、渲染 Dom 等过程。因此 subNView 是加快 Web 页面渲染的一大利器。如下为一个使用 subNView 增强后的商品详情页示例:
subNView_guide_1.png

( 手册 )[http://ask.dcloud.net.cn/docs/#//ask.dcloud.net.cn/article/12759]
在页面加载动画时,subNView 可以直接渲染出来,而后 wap 页面才慢慢渲染完毕。

"pages": [{
            "webviewId": "__W2A__deli.kong-qi.com", // 首页
            "matchUrls": [{
                "href": "http://deli.kong-qi.com/mobile"
            }, {
                "href": "http://deli.kong-qi.com/mobile/"
            }],
            "webviewParameter": { // 参考文档【http://ask.dcloud.net.cn/docs/#//ask.dcloud.net.cn/article/12749】
                "tabBar": { // 选项卡配置,仅首页支持
                    "height": "51px", // 选项卡高度,默认为 50px
                    "list": [{
                            "url": "http://deli.kong-qi.com/mobile"
                        },
                        {
                            "url": "http://deli.kong-qi.com/mobile/news.html"
                        },
                        {
                            "url": "http://deli.kong-qi.com/mobile/product.html"
                        },
                        {
                            "url": "http://deli.kong-qi.com/mobile/product.html"
                        },
                        {
                            "url": ""
                        }
                    ]
                },
                "titleNView": false
            }
        },
        { // 复用前页数据 - 列表页
            "webviewId": "nviewsList",
            "matchUrls": [{
                "href": "http://deli.kong-qi.com/mobile/product.html"
            }],
            "webviewParameter": {
                "appendJs": "JS/list.js"
            },
            "easyConfig": {
                "open": {
                    "waiting": false
                }
            }
        },
        {
            "webviewId": "about", // 首页
            "matchUrls": [{
                "href": "W:http://deli.kong-qi.com/mobile/product/show/id/*"
            }],
            "webviewParameter": {
                "subNViews": "detail.nview"

            }
        }
    ]

detail.nview 参考

<template>
    <nviews cachemaxage="86400">
        <nview id="detail_img" style="height:180px;">
            <canvas style="width:100%; height:180px; top:0;">
                <img src={data.cover} style="width:100%; height:200%;"/>
            </canvas>
            <richtext style="width:90%; position:absolute; left:5%; bottom:15px; height:40px;">
                <font id="detail_title" style="color: #fff;font-size: 16px;">{data.title}</font>                
            </richtext>
        </nview>

        <nview  style={{backgroundColor:'#ffffff',height:data.rem * 7.6,width:'100%'}}>
            <imageslider images={data.imgs}></imageslider>
        </nview>
    </nviews>

</template>
<script>
    module.exports = {
        init: function (url) {
            var self = this;
            //wap2app.getFromCache// 取得缓存数据
            wap2app.getFromCache ('detail_cache2', function (cacheData) {
                console.log (JSON.stringify (cacheData));
                if (cacheData){
                    self.setData (cacheData);// 设置页面的数据                     
                }
            });
            wap2app.getFromWebService ({
                url: 'http://hello.wap2app.dcloud.io/brand/detail',
                data: {},
                type: 'get'
            }, function (data) {
                    self.data.imgs = data;
                //TODO 如果服务端返回数据格式和模板需要的格式不同,则需要做一下转换
                self.setData (self.data);
            })
        },
        methods: {
            // 方法
        }
    };
</script>

4).easyConfig

sitemap 中的 webviewParameter 配置其实是 HTML5Plus 规范中的 Webview 的参数设置。

back

用户按下 back 按键或点击顶部标题栏的返回箭头时,将触发 wap2App 的后退逻辑。
,back 按钮是关闭当前 Webview 并显示上一个 Webview。
目前 back 节点下有 before 和 history 这 2 个配置。

before

若页面有弹出层时,此时用户按下 back 按键,其实不应该把这个 Webview 关闭。
理想的效果是按下 back 时关闭弹出的浮层,当浮层关闭后再按 back 键,才是关闭 Webview。
wap2App 会智能处理弹出层的关闭,当用户点击 back 按键时,先探测当前页面是否存在弹出层,若存在则关闭弹出层,否则关闭当前页面。

  • 全屏弹出层(比如 modal 组件),通常会提供按钮关闭弹出层,比如取消按钮或关闭图标
  • 非全屏弹出层,通常也会有取消按钮,另外大多还会有半透明遮罩层,用户点击遮罩层,也可以关闭弹出层;
    "easyConfig":{
        "back":{
            "before":[
                {
                    "popupSelector":".popup", // 弹出层选择器
                    "closeSelector":".mask", // 取消按钮选择器或遮罩层选择器
                    "eventType":"click" // 事件类型,默认为 "click"
                }
            ]
        }
    }

history

open

animation

wap2App 在打开新窗口时,新窗口默认使用从右向左的移动动画

"easyConfig":{
        "open":{
            "animation":{// 窗口切换动画配置
                "type":"slide-in-right",// 窗口动画类型
                "duration":300// 窗口动画执行时间
            }
        }
    }
  • "none": 无动画效果,立即显示页面,无任何动画效果,此效果忽略动画时间参数。
  • "slide-in-right": 页面从屏幕右侧外向内横向滑动显示
  • "slide-in-left": 页面从屏幕左侧向右横向滑动显示
  • "slide-in-top": 页面从屏幕上侧向下竖向滑动显示
  • "slide-in-bottom": 页面从屏幕下侧向上竖向滑动显示
  • "fade-in": 页面从完全透明到不透明逐渐显示
  • "zoom-out": 页面在屏幕中间从小到大逐渐放大显示
  • "zoom-fade-out": 页面在屏幕中间从小到大逐渐放大并且从透明到不透明逐渐显示
  • "pop-in": 页面从屏幕右侧滑入显示,同时上一个页面带阴影效果从屏幕左侧滑出隐藏

waiting

wap2App 在打开新窗口时,默认会显示 waiting 等待框,新 webview 的 titleUpdate 事件触发后,自动关闭 waiting 等待框

quit

用户在应用首页按下 back 按键,会触发 wap2App 的退出逻辑,应用退出的相关配置在 global->easyConfig->quit 节点下配置。

5).M 站改造

为什么要改造

我们在很多的时候,使用了原生代替,所以需要替代。

替换部分参考:

  • 标题栏
  • 头部导航
  • 底部导航

替换 2 种方式

  • 服务端判断使用场景
  • wap2App 动态修改

服务器端修改

原理判断使用的浏览器类型 navigator.userAgent,例如 PHP

<?PHP
    $agent = $_SERVER ['HTTP_USER_AGENT'];
    if (strpos ($agent,"HTML5Plus") === false){// 仅在非 5+ 引擎环境下才显示导航栏
?>
    <header class="mui-bar mui-bar-nav">
        <a class="mui-action-back mui-icon mui-icon-left-nav mui-pull-left"></a>
        <h1 class="mui-title">Web 导航栏</h1>
    </header>
<?PHP
    }
?>

wap2App 动态修改

1.动态增加样式 appendCss

"webviewParameter": {
     "appendCss":"#header{display:none}" // 插入 CSS 代码
 },

"appendCss":"page1.append.css" // 需插入的 CSS 文件路径

2.如果要自动运行调用

插入的 CSS 文件放在项目根目录下,然后遵循%webviewId%.append.css 这样的命名格式

3.动态 appendJs

跟 CSS 一样

4.下拉刷新 pullToRefresh

基于 div 方式的下拉刷新是不流畅,wap2App 框架提供了原生的下拉刷新

"webviewId":"page1",
       "matchUrls": [
           //url 匹配规则
       ],
       "webviewParameter": {
           "pullToRefresh":{
               "support":true // 启用下拉刷新
           }
       },
       "easyConfig":{}
   }

5.tabBar

原生 App 切换选项卡时,选项卡区域不变,仅内容区 view 变化;但 M 站选项卡切换时,会将整个页面重新加载,经常出现白屏现象

优化思路

通过 2 个文件嵌套形式

实现方法

  • 创建本地选项卡(client_index.html 中实现)
  • 配置选项卡页面规则(sitemap.json 中实现)

创建本地选项卡

把上面的 JS 文件注释去掉

link rel="stylesheet" type="text/CSS" href="__wap2apptabbar.css" />
<script src="__wap2apptabbar.js" type="text/JavaScript" charset="utf-8"></script>
<script>
    new TabBar ({
        list: [{
            url: "http://m.exampple.com/",
            text: "首页",
            iconPath: 'home.png',
            selectedIconPath: 'home-selected.png'
        }, {
            url: "http://m.exampple.com/list.html",
            text: "示例",
            iconPath: 'tab1.png', // 本地图标
            selectedIconPath: 'tab1-selected.png'
        }, {
            url: "http://m.exampple.com/about",
            text: "关于",
            iconPath: 'http://m.exampple.com/imgs/about.png',// 网络图标
            selectedIconPath: 'http://m.exampple.com/imgs/about-selected.png'
        }]
    });
</script>

选项卡文字颜色配置

  • 可以在 client_index.html 中通过 CSS 自定义选项卡文字颜色
    <style type="text/CSS">
    /*自定义选项卡文字颜色示例*/
    .tab-item {
        color: black;// 选项卡文字默认为黑色
    }
    .tab-item.active {
        color: blue;// 选项卡文字高亮时为蓝色
    }
    </style>

    Tips:自定义的 CSS 代码需要放在__wap2App_tabbar.css 的引用之后

6.配置选项卡页面规则

{
    "webviewId": "__W2A__m.example.com",
    "matchUrls": [
        //URL 匹配规则
    ],
    "webviewParameter": {
        "tabBar": {// 选项卡配置,仅首页支持
            "height": "50px",// 选项卡高度,默认为 50px
            "list": [
                {
                    "url": "http://m.exampple.com/" //tab1 页面地址
                }, {
                    "url": "http://m.exampple.com/list.html" //tab2 页面地址
                }, {
                    "url": "http://m.exampple.com/about.html"  //tab3 页面地址
                }
            ]
        }
    }
}

四、app.js

App () 函数接受一个 object 类型的 appConfig 参数,用来设定 wap2App 应用的生命周期函数

appConfig 参数说明:

  • options Object 配置全局参数
  • onLaunch Function 生命周期函数,监听 wap2App 应用初始化;当 wap2App 初始化完成时触发,全局只触发一次。
  • onShow Function 生命周期函数,监听 wap2App 应用显示;当 wap2App 从后台进入前台显示时触发。
  • onHide Function 生命周期函数,监听 wap2App 应用隐藏;当 wap2App 从前台进入后台显示时触发。
    前台、后台定义: 当用户按了设备 Home 键,wap2App 应用并没有直接销毁,而是进入了后台;当再次打开 wap2App 应用时,又会从后台进入前台。
    App ({
    options: {
        debug: false
    },
    /**
     * 当 wap2App 初始化完成时,会触发 onLaunch
     */
    onLaunch: function () {
        console.log ('launch');
    },
    /**
     * 当 wap2App 启动,或从后台进入前台显示,会触发 onShow
     */
    onShow: function () {
        console.log ('show');
    },
    /**
     * 当 wap2App 从前台进入后台,会触发 onHide
     */
    onHide: function () {
        console.log ('hide');
    }
    });

Page () 函数用来注册一个页面。

Page (id,pageConfig);
id 是字符串类型,表示 webview 的 id,对应 sitemap.json 中配置的"webviewId"属性值。

  • onShow Function 生命周期函数,监听 webview 显示;当对应 webview 窗口显示时触发。
  • onHide Function 生命周期函数,监听 webview 关闭;当对应 webview 窗口关闭时触发。
    Page ('page1', {
    /**
     * 当页面显示时触发
     */
    onShow: function (options) {
        console.log ('page1 show');
    },
    /**
     * 当页面关闭时触发
     */
    onClose: function () {
        console.log ('page1 hide');
    }
    });

评论区 (0)

没有记录
支持 markdown,图片截图粘贴拖拽都可以自动上传。

相关帖子

黑白课堂

如果你在.env文件下配置了变量参数,在路由缓存下会无效

| 最后更新 2020-12-11 03:05:43
3464 0
黑白课堂

laravel之Artisan命令操作,以及自己编写Artisan Console命令

| 最后更新 2021-01-13 14:24:58
3473 0
黑白课堂

JWT(JSON Web Token)是一个非常轻巧的规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。 一个JWT实际上就是一个字符串,它由三部分组成,头部、载荷与签名

| 最后更新 2021-01-13 14:25:29
3456 0
黑白课堂

扩展一个指令在blade模板中使用。

| 最后更新 2020-12-11 03:04:51
2907 0
黑白课堂

所有Laravel应用启动的中心,所有Laravel的核心服务都是通过服务提供者启动,服务提供者是应用配置的中心. >这里需要了解下IOC(控制反转)也叫依赖注入

| 最后更新 2021-01-11 03:14:14
3022 0
黑白课堂

控制对资源的访问权限,这个权限不同于RBAC(角色的权限访问控制),比如,只能操作自己的信息,可以说是拟补RBAC的更加细腻的权限。

| 最后更新 2021-01-13 14:24:00
2919 0
黑白课堂

黑白课堂 · 技术专家

专业PHP开发

年度VIP 站长创业者玉树凌风每天醒来0收入
查看更多

最新视频课程