MUI学习笔记-雷云龙

MUI

一、MUI介绍 新工程 布局

MUI的定位是:最接近原生体验的移动App的UI框架

基于mui的定位,产生了mui的几个特点,轻、小、只涉及UI、只为移动App而生、界面风格原生化。

所以请大家注意,mui有所为有所不为:

1、mui不是jq,不封装dom操作

与ui无关的mui不做,你愿意用jq或zepto就自己用,并不冲突。

但我们并不建议在移动App里引入jq或zepto这些框架,原因如下:

为了性能,层层封装的框架,尤其是遍历循环dom时,影响效率,尤其在低端Android手机上,我们费死劲了才把性能以毫秒为单位一点点提升,搞这个的dom框架进来就让很多努力又付诸东流。

原生JS挺简单,为何需要jq?

jq的成功当时是因为ie6、7、8、9、10、chrome、ff这些浏览器不兼容,让开发者崩溃,而且pc上浏览器性能好,跨平台兼容也不影响性能。但jq根本就不是为手机设计的。

手机上只有webkit浏览器(忽略wp,反正mui不支持wp),根本就不需要jq这种封装框架来操作dom。

而且HBuilder提供了代码块来简化开发,敲dg、dq,直接生成document.getElementById("")、document.querySelectorAll(""),非常快捷方便,而且执行性能非常高,而且没有浏览器兼容问题。

发现很多开发者只会jq,反正想继续在App里使用jq没有问题。但也建议大家多学学js本身。

2、mui、HTML5+、5+Runtime的关系说明

mui是一个前端框架,HTML5+是一套HTML5能力扩展规范,HTML5+ Runtime是实现HTML5+规范的强化浏览器引擎。

有点类似于bootstrap、w3c和chrome os的关系。

HTML5+规范隶属于http://www.html5plus.org,定义了HTML5规范中没有但开发者做App需要的扩展规范。

DCloud的5+ Runtime完整的实现了HTML5+规范。同时5+ Runtime还实现了Native.js,一种通过js调用几十万原生API的技术。

为了提升体验,mui势必会调用一些5+Rutime的增强能力,主要是plus.webview和plus.nativeUI。

但mui不是要替代HTML5Plus,以后也无计划替代把所有5+的webview api都包一层。

3、基础布局


一、头部核心css mui-bar mui-bar-nav

<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">hello</h1>
</header>

二、主体部分核心css mui-content

<div class="mui-content">
    主体部分....
</div>

完整代码演示

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title></title>
<script src="js/mui.min.js"></script>
<link href="css/mui.min.css" rel="stylesheet"/>
<script type="text/javascript" charset="utf-8">
mui.init();
</script>
</head>
<body>
<div>
<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">hello</h1>
</header>
<div class="mui-content">
    内容部分....
</div>
</body>
</html>

二、accordion(折叠面板) button(按钮)

img

1、折叠面板

折叠面板从二级列表中演化而来,dom结构和二级列表类似,如下:

<ul class="mui-table-view"> 
    <li class="mui-table-view-cell mui-collapse">
      <a class="mui-navigate-right" href="#">面板1</a>
      <div class="mui-collapse-content">
      <p>面板1子内容</p>
      </div>
    </li>
</ul>

可以在折叠面板中放置任何内容;折叠面板默认收缩,若希望某个面板默认展开,只需要在包含.mui-collapse类的li节点上,增加.mui-active类即可;mui官网中的方法说明,使用的就是折叠面板控件。

注意事项:
1、折叠面板布局必须在 mui-content下
2、外层使用 mui-card 包裹产生边缘

完整代码

<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">hello</h1>
</header>
<div class="mui-content">
    <div class="mui-card">
        <ul class="mui-table-view"> 
            <li class="mui-table-view-cell mui-collapse">
              <a class="mui-navigate-right" href="#">面板1</a>
              <div class="mui-collapse-content">
              <p>面板1子内容</p>
              </div>
            </li>
        </ul>
    </div>
</div>

img

2、按钮

mui默认按钮为灰色,另外还提供了蓝色(blue)、绿色(green)、黄色(yellow)、红色(red)、紫色(purple)五种色系 的按钮,五种色系对应五种场景,分别为primary、success、warning、danger、royal;使用.mui-btn类即可生成一个 默认按钮,继续添加.mui-btn-颜色值或.mui-btn-场景可生成对应色系的按钮,例如:通过.mui-btn-blue或.mui-btn- primary均可生成蓝色按钮;

普通按钮

在button节点上增加.mui-btn类,即可生成默认按钮;若需要其他颜色的按钮,则继续增加对应class即可,比如.mui-btn-blue即可变成蓝色按钮

<button type="button" class="mui-btn">默认</button>
<button type="button" class="mui-btn mui-btn-primary">蓝色</button>
<button type="button" class="mui-btn mui-btn-success">绿色</button>
<button type="button" class="mui-btn mui-btn-warning">黄色</button>
<button type="button" class="mui-btn mui-btn-danger">红色</button>
<button type="button" class="mui-btn mui-btn-royal">紫色</button>

若希望无底色、有边框的按钮,仅需增加.mui-btn-outlined类即可,代码如下:

<button type="button" class="mui-btn mui-btn-outlined">默认</button>
<button type="button" class="mui-btn mui-btn-primary mui-btn-outlined">蓝色</button>
<button type="button" class="mui-btn mui-btn-success mui-btn-outlined">绿色</button>
<button type="button" class="mui-btn mui-btn-warning mui-btn-outlined">黄色</button>
<button type="button" class="mui-btn mui-btn-danger mui-btn-outlined">红色</button>
<button type="button" class="mui-btn mui-btn-royal mui-btn-outlined">紫色</button>

三、actionsheet (操作表) badge(数字角标)

img

1、操作表

actionsheet一般从底部弹出,显示一系列可供用户选择的操作按钮; actionsheet是从popover控件基础上演变而来,实际上就是一个固定从底部弹出的popover,故DOM结构和popove类似,只是需要在含.mui-popover类的节点上增加.mui-popover-bottom、.mui-popover-action类;

<div id="sheet1" class="mui-popover mui-popover-bottom mui-popover-action ">
    <!-- 可选择菜单 -->
    <ul class="mui-table-view">
      <li class="mui-table-view-cell">
        <a href="#">菜单1</a>
      </li>
      <li class="mui-table-view-cell">
        <a href="#">菜单2</a>
      </li>
    </ul>
    <!-- 取消菜单 -->
    <ul class="mui-table-view">
      <li class="mui-table-view-cell">
        <a href="#sheet1"><b>取消</b></a>
      </li>
    </ul>
</div>

推荐使用锚点方式显示、隐藏actionsheet;若要使用js代码动态显示、隐藏actionsheet,同样在popover插件的构造方法中传入"toggle"参数即可,如下:

//传入toggle参数,用户无需关心当前是显示还是隐藏状态,mui会自动识别处理;

mui('#sheet1').popover('toggle');

完整代码

<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">hello</h1>
</header>
<div class="mui-content">
    <div style="padding:20px;">
        <input type="button" class="mui-btn-blue" value="点击这里弹出操作菜单" onclick="showPop();" />
    </div>
</div>
<div id="sheet1" class="mui-popover mui-popover-bottom mui-popover-action ">
    <!-- 可选择菜单 -->
    <ul class="mui-table-view">
      <li class="mui-table-view-cell">
        <a href="#">菜单1</a>
      </li>
      <li class="mui-table-view-cell">
        <a href="#">菜单2</a>
      </li>
    </ul>
    <!-- 取消菜单 -->
    <ul class="mui-table-view">
      <li class="mui-table-view-cell">
        <a href="#sheet1"><b>取消</b></a>
      </li>
    </ul>
</div>
<script type="text/javascript">
function showPop(){
    mui('#sheet1').popover('toggle');
}
</script>

2、数字角标

数 字角标一般和其它控件(列表、9宫格、选项卡等)配合使用,用于进行数量提示。 角标的核心类是.mui-badge,默认为实心灰色背景;同时,mui还内置了蓝色(blue)、绿色(green)、黄色(yellow)、红色 (red)、紫色(purple)五种色系的数字角标,如下:

<span class="mui-badge mui-badge-inverted">1</span>
<span class="mui-badge mui-badge-primary mui-badge-inverted">2</span>
<span class="mui-badge mui-badge-success mui-badge-inverted">3</span>
<span class="mui-badge mui-badge-warning mui-badge-inverted">4</span>
<span class="mui-badge mui-badge-danger mui-badge-inverted">5</span>
<span class="mui-badge mui-badge-royal mui-badge-inverted">6</span>

若无需底色,则增加.mui-badge-inverted类即可,如下:

<span class="mui-badge mui-badge-inverted">1</span>
<span class="mui-badge mui-badge-primary mui-badge-inverted">2</span>
<span class="mui-badge mui-badge-success mui-badge-inverted">3</span>
<span class="mui-badge mui-badge-warning mui-badge-inverted">4</span>
<span class="mui-badge mui-badge-danger mui-badge-inverted">5</span>
<span class="mui-badge mui-badge-royal mui-badge-inverted">6</span>

四、复选框 单选框 JS 获取数值

img

checkbox常用于多选的情况,比如批量删除、添加等;

1、DOM结构

<div class="mui-input-row mui-checkbox">
    <label>checkbox示例</label>
    <input name="checkbox1" value="Item 1" type="checkbox" checked>
</div>

默认checkbox在右侧显示,若希望在左侧显示,只需增加.mui-left类即可,如下:

<div class="mui-input-row mui-checkbox mui-left">
    <label>checkbox左侧显示示例</label>
    <input name="checkbox1" value="Item 1" type="checkbox">
</div>

若要禁用checkbox,只需在checkbox上增加disabled属性即可;

2、单选框**

radio用于单选的情况
DOM结构

<div class="mui-input-row mui-radio">
    <label>radio</label>
    <input name="radio1" type="radio">
</div>

默认radio在右侧显示,若希望在左侧显示,只需增加.mui-left类即可,如下:

<div class="mui-input-row mui-radio mui-left">
    <label>radio</label>
    <input name="radio1" type="radio">
</div>

若要禁用radio,只需在radio上增加disabled属性即可;
mui基于列表控件,提供了列表式单选实现;在列表根节点上增加.mui-table-view-radio类即可,若要默认选中某项,只需要在对应li节点上增加.mui-selected类即可,dom结构如下:

<ul class="mui-table-view mui-table-view-radio">
    <li class="mui-table-view-cell">
        <a class="mui-navigate-right">Item 1</a>
    </li>
    <li class="mui-table-view-cell mui-selected">
        <a class="mui-navigate-right">Item 2</a>
    </li>
    <li class="mui-table-view-cell">
        <a class="mui-navigate-right">Item 3</a>
    </li>
</ul>

列表式单选在切换选中项时会触发selected事件,在事件参数(e.detail.el)中可以获得当前选中的dom节点,如下代码打印当前选中项的innerHTML:

var list = document.querySelector('.mui-table-view.mui-table-view-radio');
list.addEventListener('selected',function(e){
    console.log("当前选中的为:"+e.detail.el.innerText);
});

3、js获取单选按钮的值

function getVals(){
    var res = getRadioRes('rds');
    if(res == null){mui.toast('请选择'); return;}
    mui.toast(res);
}
function getRadioRes(className){
    var rdsObj = document.getElementsByClassName(className);
    var checkVal = null;
    for(i = 0; i < rdsObj.length; i++){
        if(rdsObj[i].checked){checkVal = rdsObj[i].value;}
    }
    return checkVal;
}
</script>

4、js获取复选框的值

function getVals(){
    var res = getCheckBoxRes('rds');
    if(res.length < 1){
        mui.toast('请选择');
        return;
    }
    mui.toast(res);
}
function getCheckBoxRes(className){
    var rdsObj   = document.getElementsByClassName(className);
    var checkVal = new Array();
    var k        = 0;
    for(i = 0; i < rdsObj.length; i++){
        if(rdsObj[i].checked){
            checkVal[k] = rdsObj[i].value;
            k++;
        }
    }
    return checkVal;
}

五、datepicker(时间选择器)

img

完整代码:

<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">hello</h1>
</header>
<div class="mui-content">
    <div style="padding:15px;">
        <button id='pickDateBtn' type="button" class="mui-btn">选择日期</button>
    </div>
    <div style="padding:15px;">
        <button id='pickTimeBtn' type="button" class="mui-btn">选择时间</button>
    </div>
</div>
<script type="text/javascript">
document.getElementById("pickDateBtn").addEventListener('tap', function() {
    var dDate = new Date();
    //设置当前日期(不设置默认当前日期)
    dDate.setFullYear(2016, 7, 16);
    var minDate = new Date();
    //最小时间
    minDate.setFullYear(2010, 0, 1);
    var maxDate = new Date();
    //最大时间
    maxDate.setFullYear(2016, 11, 31);
    plus.nativeUI.pickDate(function(e) {
        var d = e.date;
        mui.toast('您选择的日期是:' + d.getFullYear() + "-" + (d.getMonth() + 1) + "-" + d.getDate());
    }, function(e) {
        mui.toast("您没有选择日期");
    }, {
        title: '请选择日期',
        date: dDate,
        minDate: minDate,
        maxDate: maxDate
    });
});
document.getElementById("pickTimeBtn").addEventListener('tap', function() {
    var dTime = new Date();
    //设置默认时间
    dTime.setHours(6, 0);
    plus.nativeUI.pickTime(function(e) {
        var d = e.date;
        mui.toast("您选择的时间是:" + d.getHours() + ":" + d.getMinutes());
    }, function(e) {
        mui.toast("您没有选择时间");
    }, {
        title: "请选择时间",
        is24Hour: true,
        time: dTime
    });
});

js获取当前时间

var myDate = new Date();
myDate.getYear();        //获取当前年份(2位)
myDate.getFullYear();    //获取完整的年份(4位,1970-????)
myDate.getMonth();       //获取当前月份(0-11,0代表1月)
myDate.getDate();        //获取当前日(1-31)
myDate.getDay();         //获取当前星期X(0-6,0代表星期天)
myDate.getTime();        //获取当前时间(从1970.1.1开始的毫秒数)
myDate.getHours();       //获取当前小时数(0-23)
myDate.getMinutes();     //获取当前分钟数(0-59)
myDate.getSeconds();     //获取当前秒数(0-59)
myDate.getMilliseconds();    //获取当前毫秒数(0-999)
myDate.toLocaleDateString();     //获取当前日期
var mytime=myDate.toLocaleTimeString();     //获取当前时间
myDate.toLocaleString( );        //获取日期与时间

六、dialog对话框 input表单

img

1、mui.alert() 普通提醒

参数

1、message Type: String 提示对话框上显示的内容
2、title Type: String 提示对话框上显示的标题
3、btnValue Type: String 提示对话框上按钮显示的内容
4、callback Type: Function 提示对话框上关闭后的回调函数
5、type Value: 'div'是否使用h5绘制的对话框

演示代码

mui.alert('欢迎使用Hello MUI', 'Hello MUI', function() {
   mui.toast('你刚关闭了警告框');
});

2、mui.confirm() 确定消息框

参数

1、message Type: String 提示对话框上显示的内容
2、title Type: String提示对话框上显示的标题
3、btnValue Type: Array 提示对话框上按钮显示的内容
4、callback Type: Function 提示对话框上关闭后的回调函数
5、type Value: 'div' 是否使用h5绘制的对话框

演示代码

var btnArray = ['取消', '确定'];
mui.confirm('真的要删除吗?','Hi...',new Array('否','是'),function(e){
   if(e.index == 1){mui.toast('是');}else{mui.toast('否');}
});

3、mui.prompt() 输入框

参数

message Type: String 提示对话框上显示的内容
placeholder Type: String 编辑框显示的提示文字
title Type: String 提示对话框上显示的标题
btnValue Type: Array 提示对话框上按钮显示的内容
callback Type: Function提示对话框上关闭后的回调函数
type Value: 'div' 是否使用h5绘制的对话框

演示代码

var btnArray = ['取消', '确定'];
mui.prompt('请输入您的姓名?','Hi...',new Array('取消','确定'),function(e){
    if(e.index == 1){
        mui.toast(e.value);
    }else{
        mui.toast('您取消了输入');
    }
});

4、mui.toast() 自动消失的消息框

mui.toast('hi...');

5、表单元素

基本说明:
所有包裹在.mui-input-row 类中的 input、textarea等元素都将被默认设置宽度属性为width: 100%; 。 将 label 元素和上述控件控件包裹在.mui-input-group中可以获得最好的排列。

<form class="mui-input-group">
    <div class="mui-input-row">
        <label>用户名</label>
    <input type="text" class="mui-input-clear" placeholder="请输入用户名">
    </div>
    <div class="mui-input-row">
        <label>密码</label>
        <input type="password" class="mui-input-password" placeholder="请输入密码">
    </div>
    <div class="mui-button-row">
        <button type="button" class="mui-btn mui-btn-primary" >确认</button>
        <button type="button" class="mui-btn mui-btn-danger" >取消</button>
    </div>
</form>

输入增强
mui目前提供的输入增强包括:快速删除、语音输入*5+ only和密码框显示隐藏密码。
1、快速删除:只需要在input控件上添加.mui-input-clear类,当input 控件中有内容时,右侧会有一个删除图标,点击会清空当前input的内容;

<form class="mui-input-group">
    <div class="mui-input-row">
        <label>快速删除</label>
        <input type="text" class="mui-input-clear" placeholder="请输入内容">
    </div>
</form>

2、搜索框:在.mui-input-row同级添加.mui-input-search 类,就可以使用search控件

<form class="mui-input-group">
    <div class="mui-input-row mui-search">
        <input type="search" class="mui-input-clear" placeholder="hcoder">
    </div>
</form>

3、密码框:给input元素添加.mui-input-password类即可使用

<form class="mui-input-group">
    <div class="mui-input-row">
        <label>密码框</label>
        <input type="password" class="mui-input-password" placeholder="请输入密码">
    </div>
</form>

初始化
mui在mui.init()中会自动初始化基本控件,但是 动态添加的元素需要重新进行初始化

mui('.mui-input-row input').input();

七、slide轮播

img

发布时间 : 2016-09-06 浏览 : 54801 次

img
轮播组件是mui提供的一个核心组件,在该核心组件基础上,衍生出了图片轮播、可拖动式图文表格、可拖动式选项卡、左右滑动9宫格等组件,这些组件有较多共同点。

1、Dom构造:

<div class="mui-slider">
  <div class="mui-slider-group">
    <!--第一个内容区容器-->
    <div class="mui-slider-item">
      <!-- 具体内容 -->
    </div>
    <!--第二个内容区-->
    <div class="mui-slider-item">
      <!-- 具体内容 -->
    </div>
  </div>
</div>

js部分

<script type="text/javascript">
mui.plusReady(function(){
    //获得slider插件对象
    var gallery = mui('.mui-slider');
        gallery.slider({
  	    interval:5000//自动轮播周期,若为0则不自动播放,默认为0;
    });
});
</script>

2、显示圆点

<div class="mui-slider-indicator">
    <div class="mui-indicator mui-active"></div>
    <div class="mui-indicator"></div>
</div>

3、轮播循环

若要支持循环,则需要在.mui-slider-group节点上增加.mui-slider-loop类,同时需要重复增加2张图片,图片顺序变为:4、1、2、3、4、1,代码示例如下:

<div class="mui-slider">
  <div class="mui-slider-group mui-slider-loop">
    <!--支持循环,需要重复图片节点-->
    <div class="mui-slider-item mui-slider-item-duplicate"><a href="#"><img src="4.jpg" /></a></div>
    <div class="mui-slider-item"><a href="#"><img src="1.jpg" /></a></div>
    <div class="mui-slider-item"><a href="#"><img src="2.jpg" /></a></div>
    <div class="mui-slider-item"><a href="#"><img src="3.jpg" /></a></div>
    <div class="mui-slider-item"><a href="#"><img src="4.jpg" /></a></div>
    <!--支持循环,需要重复图片节点-->
    <div class="mui-slider-item mui-slider-item-duplicate"><a href="#"><img src="1.jpg" /></a></div>
  </div>
</div>

4、轮播跳转

若要跳转到第x张图片,则可以使用图片轮播插件的gotoItem方法,例如:

var gallery = mui('.mui-slider');
gallery.slider().gotoItem(index);//跳转到第index张图片,index从0开始;

5、轮播事件

当拖动切换显示内容时,会触发slide事件,通过该事件的detail.slideNumber参数可以获得当前显示项的索引(第一项索引为0,第二项为1,以此类推),利用该事件,可在显示内容切换时,动态处理一些业务逻辑。

如下为一个可拖动式选项卡示例,为提高页面加载速度,页面加载时,仅显示第一个选项卡的内容,第二、第三选项卡内容为空。
当切换到第二、第三个选项卡时,再动态获取相应内容进行显示:

var item2Show = false,item3Show = false;//子选项卡是否显示标志
document.querySelector('.mui-slider').addEventListener('slide', function(event) {
  if (event.detail.slideNumber === 1&&!item2Show) {
    //切换到第二个选项卡
    //根据具体业务,动态获得第二个选项卡内容;
    var content = ....
    //显示内容
    document.getElementById("item2").innerHTML = content;
    //改变标志位,下次直接显示
    item2Show = true;
  } else if (event.detail.slideNumber === 2&&!item3Show) {
    //切换到第三个选项卡
    //根据具体业务,动态获得第三个选项卡内容;
    var content = ....
    //显示内容
    document.getElementById("item3").innerHTML = content;
    //改变标志位,下次直接显示
    item3Show = true;
  }
});

八、list 图文列表

1、普通列表

列表是常用的UI控件,mui封装的列表组件比较简单,只需要在ul节点上添加.mui-table-view类、在li节点上添加.mui-table-view-cell类即可,如下为示例代码

<ul class="mui-table-view">
    <li class="mui-table-view-cell">Item 1</li>
    <li class="mui-table-view-cell">Item 2</li>
    <li class="mui-table-view-cell">Item 3</li>
</ul>

若右侧需要增加导航箭头,变成导航链接,则只需在li节点下增加a子节点,并为该a节点增加.mui-navigate-right类即可,如下:

<ul class="mui-table-view">
    <li class="mui-table-view-cell"><a class="mui-navigate-right">Item 1</a></li>
    <li class="mui-table-view-cell"><a class="mui-navigate-right">Item 2</a></li>
    <li class="mui-table-view-cell"><a class="mui-navigate-right">Item 3</a></li>
</ul>

mui支持将数字角标、按钮、开关等控件放在列表中;mui默认将数字角标放在列表右侧显示,代码如下:

<ul class="mui-table-view">
    <li class="mui-table-view-cell">Item 1<span class="mui-badge mui-badge-primary">11</span></li>
    <li class="mui-table-view-cell">Item 2<span class="mui-badge mui-badge-success">22</span></li>
    <li class="mui-table-view-cell">Item 3<span class="mui-badge">33</span></li>
</ul>

2、图文列表img

图文列表继承自列表组件,主要添加了.mui-media、.mui-media-object、.mui-media-body几个类,如下为示例代码:

<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/1.jpg">
      <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/1.jpg">
      <div class="mui-media-body">
          木屋
        <p class='mui-ellipsis'>想要这样一间小木屋,夏天挫冰吃瓜,冬天围炉取暖.</p>
      </div>
    </a>
  </li>
</ul>

九、prograssbar进度条 滑块、switch开关

1、有准确值的进度条img

有准确值的进度条会显示当前进度正处于整体进度的占比位置,用户可以更直观的预期完成时间;
使用进度条控件,需要一个进度条控件容器,mui会自动识别该容器下是否有进度条控件,若没有,则自动创建。
进度条控件DOM结构:

<div id="demo1" class="mui-progressbar">
    <span></span>
</div>

初始化:

mui(container).progressbar({progress:20}).show();

progressbar初始化逻辑:
检查当前容器(container控件)自身是否包含.mui-progressbar类:
当前容器包含.mui-progressbar类,则以当前容器为目标控件,直接显示进度;
否则,检查当前容器的直接孩子节点是否包含.mui-progressbar类,若存在,则以遍历到的第一个含有.mui-progressbar类的孩子节点为目标控件,显示进度;
若当前容器的直接孩子节点,均不含.mui-progressbar类,则自动创建进度条控件;
更改显示进度条:

mui(container).progressbar().setProgress(50);

关闭进度条:

mui(container).progressbar().hide();

备注:关闭进度条一般用于动态创建(DOM中预先未定义)的进度条,调用hide方法后,会直接删掉对应的DOM节点;若已提前创建好DOM节点的进度条,调用hide方法无效;

2、滑块

img

<div class="mui-input-row mui-input-range">
    <label>Range</label>
    <input type="range" min="0" max="100">
</div>

获取滑块数值的样例代码

<div class="mui-content">
<div class="mui-input-row mui-input-range">
    <label>Range</label>
    <input type="range" min="0" max="100" id="range1">
</div>
<div style="padding:20px;">
    <input type="button" class="mui-btn" value="获取滑块值" onclick="getVal();" />
</div>
</div>
<script>
function getVal(){
    var rangeObj = mui('#range1');
    mui.toast(rangeObj[0].value);
}
</script>

3、switch 开关

mui提供了开关控件,点击滑动两种手势都可以对开关控件进行操作,UI如下:
img
默认开关控件,带on/off文字提示,打开时为绿色背景,基本class类为.mui-switch、.mui-switch-handle,DOM结构如下:

<div class="mui-switch">
  <div class="mui-switch-handle"></div>
</div>

若希望开关默认为打开状态,只需要在.mui-switch节点上增加.mui-active类即可,如下:

<!-- 开关打开状态,多了一个.mui-active类 -->
<div class="mui-switch mui-active">
  <div class="mui-switch-handle"></div>
</div>

若希望隐藏on/off文字提示,变成简洁模式,需要在.mui-switch节点上增加.mui-switch-mini类,如下:

<!-- 简洁模式开关关闭状态 -->
<div class="mui-switch mui-switch-mini">
  <div class="mui-switch-handle"></div>
</div>
<!-- 简洁模式开关打开状态 -->
<div class="mui-switch mui-switch-mini mui-active">
  <div class="mui-switch-handle"></div>
</div>

mui默认还提供了蓝色开关控件,只需在.mui-switch节点上增加.mui-switch-blue类即可,如下:

<!-- 蓝色开关关闭状态 -->
<div class="mui-switch mui-switch-blue">
  <div class="mui-switch-handle"></div>
</div>
<!-- 蓝色开关打开状态 -->
<div class="mui-switch mui-switch-blue mui-active">
  <div class="mui-switch-handle"></div>
</div>

蓝色开关上增加.mui-switch-mini即可变成无文字的简洁模式

若要获得当前开关状态,可通过判断当前开关控件是否包含.mui-active类来实现,若包含,则为打开状态,否则即为关闭状态;如下为代码示例:

var isActive = document.getElementById("mySwitch").classList.contains("mui-active");
if(isActive){
  console.log("打开状态");
}else{
  console.log("关闭状态");  
}

若使用js打开、关闭开关控件,可使用switch插件的toggle()方法,如下为示例代码:

mui("#mySwitch").switch().toggle();

4、事件

开关控件在打开/关闭两种状态之间进行切换时,会触发toggle事件,通过事件的detail.isActive属性可以判断当前开关状态。可通过监听toggle事件,可以在开关切换时执行特定业务逻辑。如下为使用示例:

document.getElementById("mySwitch").addEventListener("toggle",function(event){
  if(event.detail.isActive){
    console.log("你启动了开关");
  }else{
    console.log("你关闭了开关");  
  }
})

十、cardview卡片视图、mask遮罩

1、cardview(卡片视图)

img

使用mui-card类即可生成一个卡片容器,卡片视图主要有页眉、内容区、页脚三部分组成,结构如下:

<div class="mui-card">
    <!--页眉,放置标题-->
    <div class="mui-card-header">页眉</div>
    <!--内容区-->
    <div class="mui-card-content">内容区</div>
    <!--页脚,放置补充信息或支持的操作-->
    <div class="mui-card-footer">页脚</div>
</div>

卡片页眉及内容区,均支持放置图片; 页眉放置图片的话,需要在.mui-card-header节点上增加.mui-card-media类,然后设置一张图片做背景图即可,代码如下:

<div class="mui-card-header mui-card-media" style="height:40vw;background-image:url(../images/cbd.jpg)"></div>

若希望在页眉放置更丰富的信息,比如头像、主标题、副标题,则需使用.mui-media-body类,示例代码如下:

<div class="mui-card-header mui-card-media">
    <img src="../images/logo.png" />
    <div class="mui-media-body">
        小M
	<p>发表于 2016-06-30 15:30</p>
    </div>
</div>

小技巧图片出现默认的空白解决方案:
line-height:0px;

2、mask(遮罩蒙版)

在popover、侧滑菜单等界面,经常会用到蒙版遮罩;比如popover弹出后,除popover控件外的其它区域都会遮罩一层蒙版,用户点击蒙版不会触发蒙版下方的逻辑,而会关闭popover同时关闭蒙版;再比如侧滑菜单界面,菜单划出后,除侧滑菜单之外的其它区域都会遮罩一层蒙版,用户点击蒙版会关闭侧滑菜单同时关闭蒙版。

遮罩蒙版常用的操作包括:创建、显示、关闭,如下代码:

var mask = mui.createMask(callback);//callback为用户点击蒙版时自动执行的回调;
mask.show();//显示遮罩
mask.close();//关闭遮罩

注意:关闭遮罩仅会关闭,不会销毁;关闭之后可以再次调用mask.show();打开遮罩;

mui默认的蒙版遮罩使用.mui-backdrop类定义(如下代码),若需自定义遮罩效果,只需覆盖定义.mui-backdrop即可;

.mui-backdrop {position: fixed;top: 0;right: 0;bottom: 0;left: 0;z-index: 998;background-color: rgba(0,0,0,.3);}

十一、窗口管理以及之间数据传送

1、mui插件初始化

使用 mui.init(); 进行mui插件初始化。

2、页面初始化

在app开发中,若要使用HTML5+扩展api,必须等plusready事件发生后才能正常使用,mui将该事件封装成了mui.plusReady()方法,涉及到HTML5+的api,建议都写在mui.plusReady方法中。如下为打印当前页面URL的示例:

mui.plusReady(function(){
     console.log("当前页面URL:"+plus.webview.currentWebview().getURL());
});

3、创建子页面

在移动app开发过程中,经常遇到卡头卡尾的页面,此时若使用局部滚动,在android手机上会出现滚动不流畅的问题; mui的解决思路是:将需要滚动的区域通过单独的webview实现,完全使用原生滚动。具体做法则是:将目标页面分解为主页面和内容页面,主页面显示卡头卡尾区域,比如顶部导航、底部选项卡等;内容页面显示具体需要滚动的内容,然后在主页面中调用mui.init方法初始化内容页面。

mui.init({
    subpages:[{
        url:your-subpage-url,//子页面HTML地址,支持本地地址和网络地址
        id:your-subpage-id,//子页面标志
        styles:{
            top:subpage-top-position,//子页面顶部位置
            bottom:subpage-bottom-position,//子页面底部位置
            width:subpage-width,//子页面宽度,默认为100%
            height:subpage-height,//子页面高度,默认为100%
        },
    extras:{}//额外扩展参数
    }]
});

参数说明:styles表示窗口属性,参考5+规范中的WebviewStyle;特别注意,height和width两个属性,即使不设置,也默认按100%计算;因此若设置了top值为非"0px"的情况,建议同时设置bottom值,否则5+ runtime根据高度100%计算,可能会造成页面真实底部位置超出屏幕范围的情况;left、right同理。
代码样例
主页面index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title></title>
<script src="js/mui.min.js"></script>
<link href="css/mui.min.css" rel="stylesheet"/>
</head>
<body>
<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">hello</h1>
</header>
</body>
<script type="text/javascript">
mui.init({
     subpages:[{
         url   :'sub.html',
         id    : 'sub.html',
         styles:{
            top    : '45px',//子页面顶部位置
            bottom : '0px',//子页面底部位置
            width  : '100%',
            height : '100%'
          },
     }]
});
</script>
</html>

子页面 sub.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title></title>
<script src="js/mui.min.js"></script>
<link href="css/mui.min.css" rel="stylesheet"/>
<script type="text/javascript" charset="utf-8">
mui.init();
</script>
<div class="mui-content">
    <div class="mui-card">
        <!--页眉,放置标题-->
        <div class="mui-card-header mui-card-media">
            <img src="imgs/logo.png" />
            <div class="mui-media-body">
                小M
                <p>发表于 2016-06-30 15:30</p>
            </div>
        </div>
        <!--内容区-->
        <div class="mui-card-content" style="overflow:hidden; padding:0px; line-height:0px;">
            <img src="imgs/1.jpg" width="100%" />
        </div>
        <!--页脚,放置补充信息或支持的操作-->
        <div class="mui-card-footer">页脚</div>
    </div>
    <div class="mui-card">
        <!--页眉,放置标题-->
        <div class="mui-card-header mui-card-media">
            <img src="imgs/logo.png" />
            <div class="mui-media-body">
                小M
                <p>发表于 2016-06-30 15:30</p>
            </div>
        </div>
        <!--内容区-->
        <div class="mui-card-content" style="overflow:hidden; padding:0px;">
            <img src="imgs/1.jpg" width="100%" />
        </div>
        <!--页脚,放置补充信息或支持的操作-->
        <div class="mui-card-footer">页脚</div>
    </div>
</div>
</body>
</html>

4、打开新页面

做web app,一个无法避开的问题就是转场动画;web是基于链接构建的,从一个页面点击链接跳转到另一个页面,如果通过有刷新的打开方式,用户要面对一个空白的页面等待;如果通过无刷新的方式,用Javascript移入DOM节点(常见的SPA解决方案),会碰到很高的性能挑战:DOM节点繁多,页面太大,转场动画不流畅甚至导致浏览器崩溃; mui的解决思路是:单webview只承载单个页面的dom,减少dom层级及页面大小;页面切换使用原生动画,将最耗性能的部分交给原生实现.

mui.openWindow({
    url:new-page-url,
    id:new-page-id,
    styles:{
      top:newpage-top-position,//新页面顶部位置
      bottom:newage-bottom-position,//新页面底部位置
      width:newpage-width,//新页面宽度,默认为100%
      height:newpage-height,//新页面高度,默认为100%
      ......
    },
    extras:{
      .....//自定义扩展参数,可以用来处理页面间传值
    },
    createNew:false,//是否重复创建同样id的webview,默认为false:不重复创建,直接显示
    show:{
      autoShow:true,//页面loaded事件发生后自动显示,默认为true
      aniShow:animationType,//页面显示动画,默认为”slide-in-right“;
      duration:animationTime//页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒;
    },
    waiting:{
      autoShow:true,//自动显示等待框,默认为true
      title:'正在加载...',//等待对话框上显示的提示内容
      options:{
        width:waiting-dialog-widht,//等待框背景区域宽度,默认根据内容自动计算合适宽度
        height:waiting-dialog-height,//等待框背景区域高度,默认根据内容自动计算合适高度
        ......
      }
    }
})

代码样例
主页面index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title></title>
<script src="js/mui.min.js"></script>
<link href="css/mui.min.css" rel="stylesheet"/>
</head>
<body>
<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">hello</h1>
</header>
<div class="mui-content">
    <button type="button" class="mui-btn" onclick="openWindow();">点击这里打开新窗口</button>
</div>
</body>
<script type="text/javascript">
function openWindow(){
    mui.openWindow({
	url    : 'test.html',
	extras : {'name':'小明', 'age':18}
    });
}
</script>
</html>

子页面test.html(接收附加参数)

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title></title>
<script src="js/mui.min.js"></script>
<link href="css/mui.min.css" rel="stylesheet"/>
</head>
<body>
<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">test</h1>
</header>
<div class="mui-content">
    <div>姓名 : <span id="name"></span></div>
    <div>年龄 : <span id="age"></span></div>
</div>
</body>
<script type="text/javascript">
mui.init();
mui.plusReady(function(){
    var sData = plus.webview.currentWebview();
    var nameObj = mui('#name');
    nameObj[0].innerHTML = sData.name;
    var ageObj = mui('#age');
    ageObj[0].innerHTML = sData.age;
});
</script>
</html>

5、预加载

所谓的预加载技术就是在用户尚未触发页面跳转时,提前创建目标页面,这样当用户跳转时,就可以立即进行页面切换,节省创建新页面的时间,提升app使用体验。mui提供两种方式实现页面预加载。

方式一:通过mui.init方法中的preloadPages参数进行配置.

mui.init({
    preloadPages:[{
      url:prelaod-page-url,
      id:preload-page-id,
      styles:{},//窗口参数
      extras:{},//自定义扩展参数
      subpages:[{},{}]//预加载页面的子页面
    }],
    preloadLimit:5//预加载窗口数量限制(一旦超出,先进先出)默认不限制
});

该种方案使用简单、可预加载多个页面,但不会返回预加载每个页面的引用,若要获得对应webview引用,还需要通过plus.webview.getWebviewById方式获得;另外,因为mui.init是异步执行,执行完mui.init方法后立即获得对应webview引用,可能会失败,例如如下代码:

mui.init({
    preloadPages:[{
      url:'list.html',
      id:'list'
    }]
});
var list = plus.webview.getWebviewByid('list');//这里可能返回空;

方式二:通过mui.preload方法预加载.

var page = mui.preload({
    url:new-page-url,
    id:new-page-id,//默认使用当前页面的url作为id
    styles:{},//窗口参数
    extras:{}//自定义扩展参数
});

通过mui.preload()方法预加载,可立即返回对应webview的引用,但一次仅能预加载一个页面;若需加载多个webview,则需多次调用mui.preload()方法;

如上两种方案,各有优劣,需根据具体业务场景灵活选择;

十二、事件管理以及自定义事件

1、事件绑定可以使用addEventListener()方法监听某个特定元素上的事件外, 也可以使用.on()方法实现批量元素的事件绑定。

addEventListener示例(单个元素事件绑定):

mui.plusReady(function(){
    document.getElementById('but1').addEventListener('tap',function(){
	alert(1);
    });
});

on()示例,适用于批量元素绑定。演示代码:

<div class="mui-content">
  <ul id="list1">
    <li>小明</li>
    <li>小花</li>
    <li>小萌</li>
  </ul>
</div>
</body>
<script type="text/javascript">
mui.plusReady(function(){
  mui('#list1').on('tap', 'li', function(){
    var thisHtml = this.innerHTML;
    alert(thisHtml);
  });
});
</script>

2、事件取消

使用on()方法绑定事件后,若希望取消绑定,则可以使用off()方法。

mui('#list1').off('tap', 'li');

3、事件触发

使用mui.trigger()方法可以动态触发特定DOM元素上的事件。

var btn = document.getElementById("submit");
//监听点击事件
btn.addEventListener("tap",function () {console.log("tap event trigger");});
//触发submit按钮的点击事件
mui.trigger(btn,'tap');

4、手势事件

在开发移动端的应用时,会用到很多的手势操作,比如滑动、长按等,为了方便开放者快速集成这些手势,mui内置了常用的手势事件,目前支持的手势事件见如下列表:

点击 	
tap 	单击屏幕
doubletap 	双击屏幕
长按 	
longtap 	长按屏幕
hold 	按住屏幕
release 	离开屏幕
滑动 	
swipeleft 	向左滑动
swiperight 	向右滑动
swipeup 	向上滑动
swipedown 	向下滑动
拖动 	
dragstart 	开始拖动
drag 	拖动中
dragend 	拖动结束

5、自定义事件

在App开发中,经常会遇到页面间传值的需求,比如从新闻列表页进入详情页,需要将新闻id传递过去; Html5Plus规范设计了evalJS方法来解决该问题; 但evalJS方法仅接收字符串参数,涉及多个参数时,需要开发人员手动拼字符串; 为简化开发,mui框架在evalJS方法的基础上,封装了自定义事件,通过自定义事件,用户可以轻松实现多webview间数据传递。
添加自定义事件监听操作和标准js事件监听类似,可直接通过window对象添加,如下:

window.addEventListener('customEvent',function(event){mui.toast('ok');});

6、触发自定义事件

通过mui.fire()方法可触发目标窗口的自定义事件:
参数

target
Type: WebviewObject
需传值的目标webview
event
Type: String
自定义事件名称
data
Type: JSON
json格式的数据

7、自定义事件完整例子

主页面:

<div class="mui-content">
  <ul id="list1">
    <li id="1">新闻1</li>
    <li id="2">新闻2</li>
    <li id="3">新闻3</li>
  </ul>
</div>
</body>
<script type="text/javascript">
mui.init();
mui.plusReady(function(){
  var detailPage = mui.preload({url:'sub.html',id:'sub.html'});
  mui('#list1').on('tap', 'li', function(e){
    mui.fire(detailPage,'newsId',{id:this.getAttribute('id')});
    mui.openWindow({id:'sub.html'});
  });
});
</script>

子页面

mui.plusReady(function(){
    window.addEventListener('newsId',function(event){
        console.log(event.detail.id);
    });
});

十三、App与服务器之间的交互,ajax

1、APP与服务器之间的交互原理

img
app端(客户端)与服务端的交互其实理解起来和容易,客户端想服务器端发送请求,服务器端进行数据运算后返回最终结果。结果可以是多种格式:

1、text 文本格式
2、xml 格式
3、json 格式

2、什么是JSON?

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。

JSON 语法规则:

数据在键值对中

数据由逗号分隔

花括号保存对象

方括号保存数组
简单的例子:

{name:'小明', age:'18'}

3、使用MUI提供的Ajax工具完成与服务器端的交互

mui框架基于htm5plus的XMLHttpRequest,封装了常用的Ajax函数,支持GET、POST请求方式,支持返回json、xml、html、text、script数据类型;
本着极简的设计原则,mui提供了mui.ajax方法,并在mui.ajax方法基础上,进一步简化出最常用的mui.get()、mui.getJSON()、mui.post()三个方法。

4、mui.ajax()

参数:

url       Type: String  请求发送的目标地址
async     Type: Boolean 发送同步请求
data      {xx:xx,xxx:xxx} 发送到服务器的业务数据
dataType  "xml": 返回XML文档,"html": 返回纯文本HTML信息;,"script": 返回纯文本JavaScript代码,"json": 返回JSON数据,"text": 返回纯文本字符串
error     请求失败时触发的回调函数,该函数接收三个参数: (xhr:xhr实例对象,type:错误描述,可取值:"timeout", "error", "abort", "parsererror"、"null",errorThrown:可捕获的异常对象)
success   请求成功时触发的回调函数,该函数接收三个参数:(data:服务器返回的响应数据,类型可以是json对象、xml对象、字符串等;,textStatus:状态描述,默认值为'success', xhr:xhr实例对象)
timeout   请求超时时间(毫秒),默认值为0,表示永不超时;若超过设置的超时时间(非0的情况),依然未收到服务器响应,则触发error回调
type      请求方式,目前仅支持'GET'和'POST',默认为'GET'方式
headers   指定HTTP请求的Header

一个完整示例

<script type="text/javascript">
mui.init();
mui.plusReady(function(){
    document.getElementById('btn1').addEventListener('tap',function(){
        mui.ajax({
            url      : 'http://demo.hcoder.net/index.php',
            type     : 'GET',
            success  : function(data){
                mui.toast(data);
            },
            error    : function(xhr,type,errorThrown){
                mui.toast(type);
            }
        });
    });
});
</script>

返回JSON形式的数据请观看本视频!

5、Ajax简化模式

mui.post()方法是对mui.ajax()的一个简化方法,直接使用POST请求方式向服务器发送数据、且不处理timeout和异常(若需处理异常及超时,请使用mui.ajax()方法),使用方法: mui.post(url[,data][,success][,dataType]),如上登录鉴权代码换成mui.post()后,代码更为简洁,如下:

mui.post('http://server-name/login.php',{
    username:'username',
    password:'password'
},function(data){
    //服务器返回响应,根据响应结果,分析是否登录成功;
		...
    },'json'
);

mui.get()方法和mui.post()方法类似,只不过是直接使用GET请求方式向服务器发送数据、且不处理timeout和异常(若需处理异常及超时,请使用mui.ajax()方法),使用方法: mui.get(url[,data][,success][,dataType]),如下为获得某服务器新闻列表的代码片段,服务器以json格式返回数据列表

mui.get('http://server-name/list.php',{category:'news'},function(data){
    //获得服务器响应
    ...
    },'json'
);

mui.getJSON()方法是在mui.get()方法基础上的更进一步简化,限定返回json格式的数据,其它参数和mui.get()方法一致,使用方法: mui.get(url[,data][,success]),如上获得新闻列表的代码换成mui.getJSON()方法后,更为简洁,如下:

mui.getJSON('http://server-name/list.php',{category:'news'},function(data){
    //获得服务器响应
    ...
    }
);

eader


一个完整示例

```js
<script type="text/javascript">
mui.init();
mui.plusReady(function(){
    document.getElementById('btn1').addEventListener('tap',function(){
        mui.ajax({
            url      : 'http://demo.hcoder.net/index.php',
            type     : 'GET',
            success  : function(data){
                mui.toast(data);
            },
            error    : function(xhr,type,errorThrown){
                mui.toast(type);
            }
        });
    });
});
</script>

返回JSON形式的数据请观看本视频!

5、Ajax简化模式

mui.post()方法是对mui.ajax()的一个简化方法,直接使用POST请求方式向服务器发送数据、且不处理timeout和异常(若需处理异常及超时,请使用mui.ajax()方法),使用方法: mui.post(url[,data][,success][,dataType]),如上登录鉴权代码换成mui.post()后,代码更为简洁,如下:

mui.post('http://server-name/login.php',{
    username:'username',
    password:'password'
},function(data){
    //服务器返回响应,根据响应结果,分析是否登录成功;
		...
    },'json'
);

mui.get()方法和mui.post()方法类似,只不过是直接使用GET请求方式向服务器发送数据、且不处理timeout和异常(若需处理异常及超时,请使用mui.ajax()方法),使用方法: mui.get(url[,data][,success][,dataType]),如下为获得某服务器新闻列表的代码片段,服务器以json格式返回数据列表

mui.get('http://server-name/list.php',{category:'news'},function(data){
    //获得服务器响应
    ...
    },'json'
);

mui.getJSON()方法是在mui.get()方法基础上的更进一步简化,限定返回json格式的数据,其它参数和mui.get()方法一致,使用方法: mui.get(url[,data][,success]),如上获得新闻列表的代码换成mui.getJSON()方法后,更为简洁,如下:

mui.getJSON('http://server-name/list.php',{category:'news'},function(data){
    //获得服务器响应
    ...
    }
);
  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值