混合开发

混合开发,是介于 H5 和原生之间的一种开发模式,既有原生的部分,也有 H5 的部分,结合了各自有优点,这种开发模式,既可以做到跨平台,也能上各大应用市场。


混合开发介绍

  1. 移动应用开发的三种方式
    • Native App: 本地应用程序(原生 App)
    • Web App:网页应用程序(移动 web)
    • Hybrid App:混合应用程序(混合 App):美团,爱奇艺,微信
  2. web 应用
    • 优点
      • 不需要下载,不需要安装,保证最新版本
      • 对于开发者相对简单
    • 缺点
      • 浏览器提供的 api,大部分系统级硬件不能用
      • 性能不如原生
  3. 混合开发:native app 和 web app 的结合,最外有层壳(原生),里面放的网页系统提供的 Webview(网页渲染控件)
    • 优点
      • 兼容多平台
      • 顺利访问手机多种功能
      • App stroe中可以下载(web 应用中套原生应用的外壳)
    • 缺点
      • 不确定上线时间
      • 用户体验不如本地应用
      • 性能较慢

MUI 初步认识

https://dev.dcloud.net.cn/mui/
这是他的官网


HBulid 初入时遇到的坑

Q0:Uncaught ReferenceError: plus is not defined (提示: 请在 plus ready 后再调用 plus api)

这个报错的话应该是你没有添加事件,上来就运行 mui .XXX 的控件了
我解决的方案就是加个事件来触发mui.XXX

Q1:上机运行报错 error

修改文件夹的名字,不要有横杠 - 或是下划线 _ 之类的符号(我找了好久的错误,浏览器能运行,到手机上就不好使了)
在这里插入图片描述
报错信息如下

在这里插入图片描述

Q2:手机上显示主页怎么调?

不用每次都修改 index,而是
在这里插入图片描述

Q3:mui 是 5+ 封装的

所以 5+的方法一定要上手机真机上测试,手游模拟器也行,chrome 等 pc 浏览器是测不出来的,因为没有安卓环境
他俩的封装关系类似 Bootstrap 和 css 之间的关系,Bootstrap 是 css 的封装


MUI 框架

Dialog 消息框

如果想要一个消息框类似如下,可以写这样的代码

在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<body>
<script src="../../js/mui.js"></script>
<script type="text/javascript">
mui.init();
</script>
<button class="btn1">弹出提示框</button>
</body>
<script type="text/javascript">
var btn = document.querySelector(".btn1");
var arr = ["取消", "确定"];
btn.onclick = function () {
mui.confirm("这是一段内容", "标题", arr, function (e) {
console.log(e);
});
};
</script>

如果想把她的样式变成 IOS 的,可以在confrim的参数里添加 div

1
2
3
4
5
6
7
8
9
10
11
12
btn.onclick = function () {
mui.confirm(
"这是一段内容",
"标题",
arr,
function (e) {
console.log(e);
/* 在下面添加 'div' */
},
"div"
);
};

图文列表

样式如下在这里插入图片描述
代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<ul class="mui-table-view">
<li class="mui-table-view-cell mui-media">
<a href="javascript:;">
<img class="mui-media-object mui-pull-left" src="../../imgs/girl1.png" />
<div class="mui-media-body">
幸福
<p class="mui-ellipsis">
能和心爱的人一起睡觉,是件幸福的事情;可是,打呼噜怎么办?
</p>
</div>
</a>
</li>
<li class="mui-table-view-cell mui-media">
<a href="javascript:;">
<img class="mui-media-object mui-pull-left" src="../../imgs/girl1.png" />
<div class="mui-media-body">
木屋
<p class="mui-ellipsis">
想要这样一间小木屋,夏天挫冰吃瓜,冬天围炉取暖.
</p>
</div>
</a>
</li>
<li class="mui-table-view-cell mui-media">
<a href="javascript:;">
<img class="mui-media-object mui-pull-left" src="../../imgs/girl1.png" />
<div class="mui-media-body">
CBD
<p class="mui-ellipsis">烤炉模式的城,到黄昏,如同打翻的调色盘一般.</p>
</div>
</a>
</li>
</ul>

侧滑菜单

样式类似这样的
在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!-- 在最外层这个类里改变样式
mui-scalable 类似手机qq
mui-slide-in 菜单也会跟随着滑动
-->
<!-- 侧滑导航根容器 -->
<div class="mui-off-canvas-wrap mui-draggable mui-scalable">
<!-- 菜单容器 -->
<aside class="mui-off-canvas-left">
<div class="mui-scroll-wrapper">
<div class="mui-scroll">
<!-- 菜单具体展示内容 -->
菜单具体展示内容
</div>
</div>
</aside>
<!-- 主页面容器 -->
<div class="mui-inner-wrap">
<!-- 主页面标题 -->
<header class="mui-bar mui-bar-nav">
<a class="mui-icon mui-action-menu mui-icon-bars mui-pull-left"></a>
<h1 class="mui-title">标题</h1>
</header>
<div class="mui-content mui-scroll-wrapper">
<div class="mui-scroll">
<!-- 主界面具体展示内容 -->
主界面具体展示内容
</div>
</div>
</div>
</div>

选择器

样式如下

在这里插入图片描述
代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<head>
<meta charset="utf-8" />
<title></title>
<meta
name="viewport"
content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"
/>
<link href="../../css/mui.css" rel="stylesheet" />
<link rel="stylesheet" href="../../css/mui.picker.css" />
<link rel="stylesheet" href="../../css/mui.poppicker.css" />
</head>

<body>
<script src="../../js/mui.js"></script>
<!-- picker的引入要在mui 的下面 -->
<script src="../../js/mui.picker.js"></script>
<script src="../../js/mui.poppicker.js"></script>
<script type="text/javascript">
mui.init();
</script>
<button class="btn1">点我触发选择器</button>
</body>

<script>
(function ($, doc) {
$.init();
var user = new $.PopPicker();
user.setData([
{ value: "cxq", text: "陈晓晴" },
{ value: "zzh", text: "张子涵" },
{ value: "hsj", text: "黄圣杰" },
]);
var btn = doc.querySelector(".btn1");
btn.addEventListener("tap", function () {
user.show(function (items) {
console.log(items);
//return false 弹框不会自动关闭
});
});
})(mui, document);
</script>

城市三级联动

想要做这个需要以下文件

链接:https://pan.baidu.com/s/1vGK2rjoTJ4SLpPdiv6UgDg
提取码:219x

样式如下
在这里插入图片描述

代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<head>
<meta charset="utf-8" />
<title></title>
<meta
name="viewport"
content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"
/>
<link href="../../css/mui.css" rel="stylesheet" />
<link rel="stylesheet" href="../../css/mui.picker.css" />
<link rel="stylesheet" href="../../css/mui.poppicker.css" />
</head>

<body>
<script src="../../js/mui.js"></script>
<script src="../../js/mui.picker.js"></script>
<script src="../../js/mui.poppicker.js"></script>
<script src="../../js/city.data-3.js"></script>
<script type="text/javascript">
mui.init();
</script>
<!-- 显示的容器 -->
<div id="what"></div>
</body>
<script>
/* 设置选择器的层级 */
var picker = new mui.PopPicker({
layer: 3,
});
picker.setData(cityData3);
picker.pickers[0].setSelectedIndex(1);
picker.pickers[1].setSelectedIndex(1);
picker.show(function (SelectedItem) {
console.log(SelectedItem);
//显示你选的是那个城市
what.innerHTML = SelectedItem[0].text + SelectedItem[1].text;
});
</script>

选项卡

样式如下
在这里插入图片描述

代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<body>
<script src="../../js/mui.js"></script>
<script type="text/javascript">
mui.init();
</script>
<header class="mui-bar mui-bar-nav">
<a href="" class="mui-icon mui-action-menu mui-icon-bars mui-pull-left"></a>
<h1 class="mui-title">标题你好</h1>
</header>
<nav class="mui-bar mui-bar-tab">
<a href="#fir" class="mui-tab-item mui-active">
<span class="mui-icon mui-icon-home"></span>
<span class="mui-tab-label">首页</span>
</a>
<a href="#sec" class="mui-tab-item ">
<span class="mui-icon mui-icon-help"></span>
<span class="mui-tab-label">help</span>
</a>
<a href="#thr" class="mui-tab-item ">
<span class="mui-icon mui-icon-home"></span>
<span class="mui-tab-label">charset</span>
</a>
<a href="#for" class="mui-tab-item ">
<span class="mui-icon mui-icon-home"></span>
<span class="mui-tab-label">首页</span>
</a>
</nav>
<div class="mui-content">
<div id="fir" class="mui-control-content mui-active">1</div>
<div id="sec" class="mui-control-content">22</div>
<div id="thr" class="mui-control-content ">333</div>
<div id="for" class="mui-control-content">4444</div>
</div>
</body>

导航栏滑动透明度

卧槽不知道咋写标题了,看效果吧
在这里插入图片描述
具体实现如下

1
2
3
4
5
6
7
<!-- 导航栏滑动逐渐变得不透明,只需要这里的一个类 mui-bar-transparent-->
<header class="mui-bar mui-bar-transparent">
<h1 class="mui-title">标题</h1>
</header>
<div id="" class="mui-content">
<img src="../../imgs/girl1.png" />
</div>

滑动选项

样式如下
在这里插入图片描述
代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<div class="mui-content">
<ul class="mui-table-view">
<!-- 左滑删除 -->
<li class="mui-table-view-cell">
<div class="mui-slider-right mui-disabled">
<a class="mui-btn mui-btn-red">删除</a>
</div>
<div class="mui-slider-handle">左滑删除</div>
</li>

<!-- 右滑删除 -->
<li class="mui-table-view-cell">
<div class="mui-slider-left mui-disabled">
<a class="mui-btn mui-btn-red">删除</a>
<a class="mui-btn mui-btn-blue">删除</a>
</div>
<div class="mui-slider-handle">右滑删除</div>
</li>

<!-- 左右滑删除 -->
<li class="mui-table-view-cell">
<div class="mui-slider-left mui-disabled">
<a class="mui-btn mui-btn-red">删除</a>
</div>
<div class="mui-slider-right mui-disabled">
<a class="mui-btn mui-btn-red">删除</a>
</div>
<div class="mui-slider-handle">左右滑删除</div>
</li>
</ul>
</div>

图片查看

所需要的插件如下
链接:https://pan.baidu.com/s/1ISSSYmnqYv8br8qZOaNtlA
提取码:d8k6
图片查看器

代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<meta
name="viewport"
content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"
/>
<!-- 注意你的路径是否对应,我的修改过 -->
<link href="../../css/mui.css" rel="stylesheet" />
<!-- 引入应在mui.css下面 防止不必要的错误 -->
<link rel="stylesheet" href="../../css/imageV.css" />
</head>

<body>
<script src="../../js/mui.js"></script>
<script type="text/javascript">
mui.init();
</script>
<!-- 敲mheader就会出来了 -->
<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">标题</h1>
</header>
<div class="mui-content">
<!-- 为了层级结构一样 -->
<div class="mui-content-padded"></div>

<!-- 如果data-preview-group="1" 组相等的话就会在放大的时候滑动查看一族内的图片-->
<p>这是第一张图</p>
<p>
<img
src="../../imgs/girl1.png"
alt=""
data-preview-src=""
data-preview-group="1"
/>
</p>
<p>这是第2张图</p>
<p>
<img
src="../../imgs/girl2.png"
alt=""
data-preview-src=""
data-preview-group="1"
/>
</p>
</div>
</body>
<script type="text/javascript" src="../../js/mui.zoom.js"></script>
<script type="text/javascript" src="../../js/mui.previewimage.js"></script>
<script type="text/javascript">
/* 初始化控件是必须的 */
mui.previewImage();
</script>
</html>

窗口管理

双 webview 模式

Q1:在 mobile app 开发过程中,经常会出现 共用的导航栏或者选项卡,每次打开页面都需要重新渲染,而且容易出现卡头卡尾的现象。并且此时若使用局部滚动,在 android 手机上会出现滚动不流畅的问题;

解决如上问题,官方给了两种方法,这里说其中一种叫 双 webview 模式
在 index 中插入脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* 嵌入 
url为你要插入的页面路径
id就是给它起名字
*/
mui.init({
subpages: [
{
url: "html/0318/image.html",
id: "image.html",
styles: {
top: "45px", //mui标题栏默认高度为45px;
bottom: "0px", //默认为0px,可不定义;
},
},
],
});

嵌入

官方给的工作原理如下
在这里插入图片描述

页面协值跳转

使用的方法mui.openWindow

1
2
3
4
5
6
7
8
/* 这是传值的页面 ,我传递一个 name:"cao" 给B页面*/
mui.openWindow({
url: "bPage.html",
id: "bPage.html",
extras: {
name: "cao",
},
});

接收

1
2
3
4
5
6
7
/* 这是接收值的页面 */
mui.plusReady(function () {
//这个plusReady只能在手机上显示!!!!!!!
var self = plus.webview.currentWebview();
//吐司显示
mui.toast(self.name);
});

预加载

预加载的测试思路

  1. 通过 mui.openWindow()打开预加载的页面,看是否带有转圈圈的 loading 框,如果有,就说明没有预加载,如果秒跳转就说明预加载成功
  2. var array = plus.webview.all();来获取所有 webview,看是否有预加载的 webview

官方文档给了两种方法

mui.init mui.preload
优点 可以预加载多个页面 性能好
缺点 可能造成的页面栈过多 只能预加载一个页面
特性 异步(解决:设置延时定时器) 同步

HTML5+ API

具体使用详见如下链接,这里叙述些重要的 API
https://www.dcloud.io/docs/api/zh_cn/webview.html

create

用途:创建新的 Webview 窗口

1
WebviewObject plus.webview.create( url, id, styles, extras );
  • 这是创建一个webview 窗口,而不是新的网页!!,新创建的窗口等待我们 show 方法使用
  • 如果 style 对象是空的,那么写个空 对象就行 let newWindow = plus.webview.create("new.html","new.html",{},{msg:'nima'});

下拉刷新

单 webview 模式

样式如下
下拉刷新
代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<body>
<div id="pullfresh" class="mui-content mui-scroll-wrapper">
<div class="mui-scroll">
<ul class="mui-table-view mui-table-view-chevron"></ul>
</div>
</div>
</body>

<script type="text/javascript">
/* 下拉刷新更新信息 */
mui.init({
pullRefresh: {
container: "#pullfresh",
down: {
style: "circle",
callback: pulldownRefresh,
},
},
});

window.onload = function () {
// 初始化20条数据
addDate(20);
};
function addDate(item) {
var table = document.querySelector(".mui-table-view");
var cell = document.querySelectorAll(".mui-table-view-cell");
// console.log(cell.length);
for (let i = cell.length, len = i + item; i < len; i++) {
var li = document.createElement("li");
li.className = "mui-table-view-cell";
li.innerHTML = "<a class='mui-navigate-right'> " + (i + 1) + " </a>";

// 在末尾追加
// table.appendChild(li,table.firstChild);

table.insertBefore(li, table.firstChild);
}
}

function pulldownRefresh() {
setTimeout(function () {
addDate(5);
mui("#pullfresh").pullRefresh().endPulldownToRefresh();
mui.toast("已经刷新5个元素");
}, 1500);
}
</script>