功能方面,小程序应该比原生App更单一;
设计方面,小程序应该比原生App更简洁;
使用场景方面,小程序比原生App更明确。
(微信小程序应该聚焦某个功能点,成为随时解决用户单一需求的工具)javascript
注意:一个邮箱对应一个公众号或小程序。css
条件:
1.可快速认证的小程序:企业、媒体、政府和其余组织类型的小程序;
2.要求公众号必须先完成微信认证;
3.公众号与小程序关联,且主体相同。
申请入口:
登陆公众号->小程序->小程序管理->关联小程序 -> 添加
登陆公众号->小程序->小程序管理->关联小程序 ->选中相关小程序(详情)->申请
html
详情见: http://kf.qq.com/faq/170427FvEZNN170427YJjiAJ.htmlvue
接下来就能够下载微信开发者工具来建立小程序了,AppId能够在小程序管理后台“设置”–“开发设置”中查看。
java
生命周期函数官方教程:https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/page.html
git
通常只用于建立pages目录下的文件夹(页面代码文件夹)web
与 CSS 相比,WXSS 扩展的特性有:尺寸单位 样式导入
详情见:https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxss.htmljson
App.js的App()函数内不只能够定义全局函数和数据,还能够指定小程序的生命周期函数。canvas
App({ onLaunch: function(){ //生命周期函数-监听小程序初始(当小程序初始化彻底时触发,全局只触发一次) }, onShow: function(){ //生命周期函数-监听小程序显示(小程序启动和后台进入前台显示时触发) }, onHide: function(){ //生命周期函数-监听小程序隐藏(当小程序从前台进入后台是触发) }, onError: function(){ //错误监听函数(当小程序发生脚本错误或者api调用失败时会触发onError并上错误信息) }, //任意数据 globalData: 'i am a global data', globalFun : function(){ //任意函数 } })
在页面的js文件中调用全局函数或者数据(不要调用生命周期函数):小程序
var AppInstance = getApp(); console.log(AppInstance.globalData);
- App()函数必须在App.js中注册,且不能注册多个
- 不要在App()函数内使用getApp(),使用this就能够拿到App实例。
在每一个页面文件夹的js文件中经过Page()函数注册一个页面,和App()函数同样接受一个object参数,其指定一个页面的初始数据、生命周期函数、事件处理函数等页面的全部业务逻辑。
// pages/index/index.js Page({ data: { //页面的初始数据,做为页面的第一次渲染。data将以JSON的形式由逻辑层传至渲染层, //因此数据必须能够转换成JSON格式——字符串,数字,布尔值,对象或者数组。(通常都是写成对象) }, onLoad: function (options) { //生命周期函数--监听页面加载。一个页面只会调用一次, //接收页面参数能够获取wx.navigateTo和wx.redirectTo及<navigator />中的query }, onReady: function () { //生命周期函数--监听页面初次渲染完成。一个页面只会调用一次,表明页面已经准备稳当, //能够和视图层进行交互,对界面设置如wx.setNavigationBarTitle请在onReady以后进行 }, onShow: function () { //生命周期函数--监听页面显示。每次打开页面都会调用一次。 }, onHide: function () { //生命周期函数--监听页面隐藏。当navigateTo或底部Tab切换时调用。 }, onUnload: function () { //生命周期函数--监听页面卸载。当redirectTo或者navigateBack时调用。 }, onPullDownRefresh: function () { //页面相关事件处理函数--监听用户下拉动做。须要在config的window选项中开启enablePullDownRefresh。 //处理完数据刷新后,wx.stopPullDownRefresh能够中止当前页面的下拉刷新 }, onReachBottom: function () { //页面上拉触底事件的处理函数。当上拉至底部时就会触发onReachBottom函数来进行相应动做, //这在大数据量显示的时候颇有用 }, onShareAppMessage: function () { //用户点击右上角分享。只有定义了此事件处理函数,右上角菜单才会显示“分享”按钮,用户单击“分享”按钮时调用,此事件须要return一个Object(参数title,desc,path),用于自定义分享内容。 }, pageFun :function(){ //开发者能够添加任意函数(包括事件处理函数)或者数据,在Page()函数内能够用this获取实例访问. } })
该函数接收一个对象参数,用于将this.data中的key对应的值改变成对象参数的值。注意,该方法也可用于添加数据。
<!--pages/index/index.wxml--> <view>{{ text }}</view> <button bindtap='changeText'>Change normal data</button> <view>{{ array[0].text }}</view> <button bindtap='changeTextInArray'>Change array data</button> <view>{{ object.text }}</view> <button bindtap='changeTextInObject'>Change object data</button> <view>{{ newData.text }}</view> <button bindtap='addNewData'>Add new data</button>
// pages/index/index.js Page({ data: { //页面的初始数据,做为页面的第一次渲染。data将以JSON的形式由逻辑层传至渲染层, //因此数据必须能够转换成JSON格式——字符串,数字,布尔值,对象或者数组。 text: 'init data', array: [{text: 'init data'}], object: { text: 'init data' } }, changeText: function(){ this.setData({ // this.data.text = 'changed data' //it can not work 无效 text: 'changed data' }) }, changeTextInArray: function(){ this.setData({ 'array[0].text': 'changed data' }) }, changeTextInObject: function(){ this.setData({ 'object.text': 'changed data' }) }, addNewData: function(){ this.setData({ 'newData.text': 'changed data' }) },
注意,单次设值数据不能超过1024kb.
wxml中的动态数据来自js文件中的Page的data。经过双花括号{{ }}进行绑定。在须要绑定的任意位置{{ data }}写入,即绑定数据的地方都须要{{ }},这点和vue不一样。一样,和vue等双向数据绑定框架一致,{{ }}差值表达式内能够进行一些三元运算、数学运算、逻辑判断、路径运算等简单的运算。
<!-- 这里block的wx:if下面的写法都是错的,不能正确渲染。缘由嘛,如今还不了解 --> <block wx:if= {{ true }} > <!-- 报错 --> <block wx:if= "true" > <!-- 不论是true仍是false 都是至关于true--> <block wx:if= true > <!-- 不论是true仍是false 都是至关于true -->
注意,block标签并非一个组件,仅仅是一个包装元素,不会再页面中作任何渲染,只接受控制属性。
在组件上使用wx:for控制属性绑定一个数组,便可使用数组中的各项数据重复渲染该组件。
举个栗子,
首先js中定义个对象数组:
// pages/index/index.js Page({ data: { array: [{name: '小明'},{name: '小红'},{name: '小白'}] } })
而后定义页面结构:
<!--pages/index/index.wxml--> <view wx:for="{{ array }}"> {{ index }}: {{ item.name }} </view>
index 对应每一项的下标,从0开始。 item 对应当前项。
可使用wx:for-item 和 wx:for-index 指定变量名。以下,
<view wx:for="{{ array }}" wx:for-index="num" wx:for-item="itemName"> {{ num }}: {{ itemName.name }} </view>
和wx:if同样,可使用block来渲染多个组件。
<!--pages/index/index.wxml--> <block wx:for="{{ array }}"> <view>{{ index }}</view> <view>姓名: {{ item.name }} </view> <view>年龄: {{ item.age }} </view> <view>分数: {{ item.score }} </view> </block>
若是表中项目位置会动态改变或者有新的项目添加到列表中,而且但愿列表中的项目保持本身的特征和状态,须要指定wx:key。
wx:key 的值有两种形式:
① 字符串。要求该字符串是列表中的惟一,且不能动态改变。
②保留关键字 *this。*this 表明for循环中item自己,须要保证item是惟一的字符串或者数字。
<select wx:for="{{ objectArray}}" wx:key="unique" style="display:block">{{ item.id }}</select> //下面是index.js文件 Page({ data: { objectArray:[ { id: 5, unique: 'unique_1' }, { id: 4, unique: 'unique_2' }, { id: 3, unique: 'unique_3' }, { id: 2, unique: 'unique_4' }, { id: 1, unique: 'unique_5'} ] } })
若是明确地知道列表是静态或者不关心其位置,可不指定。可是会有warning,忽略便可。
定义模板:使用template标签,name属性声明模板名称。
使用模板:is属性声明使用的模板,data属性引入数据。
可以使用三元运算符动态决定具体渲染哪一个模板。ps:发现这里使用模板的时候能够写成自闭和标签
<!--pages/index/index.wxml--> <template name="odd"> odd </template> <template name="even"> even </template> <block wx:for="{{ [1,2,3,4,5,6] }}"> <view> <template is="{{ item % 2 == 0 ? 'even' : 'odd' }}" /> </view> </block>
①import引用
在该文件中引用目标文件定义的template
②include引用
将目标文件除了template以外的整个代码引入,至关于复制到include位置。
<!--pages/headline/headline.wxml--> <view class='section'> <view class='section_title'>横向滚动</view> <scroll-view scroll-x="true" style='width: 100%'> <view class="main"> <view class="box">推荐</view> <view class="box">推荐</view> <view class="box">推荐</view> <view class="box">推荐</view> <view class="box">推荐</view> <view class="box">推荐</view> <view class="box">推荐</view> <view class="box">推荐</view> <view class="box">推荐</view> <view class="box">推荐</view> </view> </scroll-view> </view>
/* pages/headline/headline.wxss */ .main{ display: flex; width: 1000%; } .main .box{ width:100%; height: 400px; background-color: yellow; } .main .box:nth-child(even){ background-color: yellowgreen; }
3. 纵向滚动
<!--pages/index/index.wxml--> <!-- scroll-y : 容许纵向滚动--> <!-- bindscrolltoupper : 指定滚动到顶部/左边触发的事件--> <!-- bindsrolltolower : 指定滚动到底部/右边触发的事件--> <!-- bindscroll : 指定滚动时触发的事件--> <!-- scroll-into-view : 滚动到子元素指定id区域--> <!-- scroll-top : 设置竖向滚动条的位置--> <!-- upper-threshold: 距顶部/左边多远时(单位px),触发scrolltoup事件 默认值:50--> <!-- lower-threshold: 距底部/右边多远时(单位px),触发scrolltoup事件 默认值:50--> <view class='section'> <view class='section_title'>纵向滚动</view> <scroll-view scroll-y="true" bindscrolltoupper="upper" bindsrolltolower="lower" bindscroll="scroll" scroll-into-view="{{ toView }}" scroll-top="{{ scrollTop }}"> <view id='green'></view> <view id='red'></view> <view id='yellow'></view> <view id='blue'></view> <view id='pink'></view> <view id='black'></view> </scroll-view> <view class='btn-area'> <button type='default' bindtap="tap">click me scroll into view</button> <button type='default' bindtap="tapMove">click me to scroll</button> </view> </view>
/* pages/index/index.wxss */ scroll-view{ height: 200px; } #green{ width: 100%; height: 100px; background-color: green; } #red{ width: 100%; height: 100px; background-color: red; } #yellow{ width: 100%; height: 100px; background-color: yellow; } #blue{ width: 100%; height: 100px; background-color: blue; } #pink{ width: 100%; height: 100px; background-color: pink; } #black{ width: 100%; height: 100px; background-color: black; } .section .btn-area button{ margin: 10px; }
// pages/index/index.js Page({ data: { toView: 'red', scrollTop: 100 }, upper: function(e){ console.log("=====upper====" + e); }, lower: function (e) { console.log("=====lower====" + e); }, scroll: function (e) { console.log("=====scroll====" + e); }, tap: function(){ this.setData({ toView: 'green', scrollTop : 0 //注意这里滚动都green,可是scrollTop依旧为以前的值。 }); }, tapMove: function(){ this.setData({ scrollTop: this.data.scrollTop + 100 }); } })
(1) 请勿在scroll-view 中使用 textarea 、map 、canvas 、video 组件
(2) scroll-into-view 优先级高于 scroll-top
(3) 在scroll-view 中滚动没法触发 onPullDownRefresh
<!--pages/cook/cook.wxml--> <view class='header'> <!-- indicator-dots: 是否显示面板指示点 默认:false--> <!-- autoplay: 是否自动切换 默认值:false --> <!-- current: 当前所在页面的index(开始的位置) 默认值:0 --> <!-- interval: 自动切换时间间隔 默认值:5000 --> <!-- duration: 切换动画时长 默认值:500 --> <!-- circular: 是否采用衔接滑动(就是能重复) 默认值:false --> <!-- bindchange: current改变时会触发change事件 --> <swiper indicator-dots='true' autoplay='true' current='1' interval='3000' duration='1000' circular='true' bindchange='hasChange'> <block wx:for="{{ imgUrls }}"> <swiper-item> <image src='{{ item }}' class='silde-image' style='width:100%; height:158px'></image> </swiper-item> </block> </swiper> </view>
// pages/cook/cook.js Page({ data: { imgUrls: [ 'https://s1.cdn.xiangha.com/caipu/201707/031210164843.jpg/MHgw.webp', 'https://s3.cdn.xiangha.com/caipu/201707/031455386879.jpg/MHgw.webp', 'https://s1.cdn.xiangha.com/caipu/201511/271833544565.jpg/MHgw.webp' ] }, hasChange: function () { console.log('changed'); } })
swiper滑块的页签切换效果实现多种类别方式切换
<!--pages/me/me.wxml--> <view class='content'> <view class='loginTitle'> <view class="{{ currentTab==0?'select':'default' }}" data-current='0' bindtap='switchNav'> 帐号密码登陆 </view> <view class="{{ currentTab==1?'select':'default' }}" data-current='1' bindtap='switchNav'> 手机快捷登陆 </view> </view> <view class='hr'></view> <swiper current='{{ currentTab }}' style='height:{{ winHeight }}px'> <swiper-item> <view class='area'>帐号密码登陆区域</view> </swiper-item> <swiper-item> <view class='area'>手机快捷登陆区域</view> </swiper-item> </swiper> </view>
/* pages/me/me.wxss */ .loginTitle{ display: flex; width: 100%; } .select{ font-size: 12px; color: red; width: 50%; text-align: center; height: 45px; line-height: 45px; border-bottom: 5rpx solid red; } .default{ font-size: 12px; margin: 0 auto; padding: 15px; } .hr{ border: 1px solid #ccc; opacity: 0.2; } .area{ margin-top: 10px; border:1px solid #ccc; width: 99%; height: 200px; text-align: center; }
// pages/me/me.js Page({ data: { currentTab: 0, winWidth: 0, winHeight: 0 }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { var page = this; wx.getSystemInfo({ success: function(res) { console.log(res); page.setData({ winWidth: res.windowWidth }); page.setData({ winHeight: res.windowHeight }); }, }) }, switchNav: function(e){ var page = this; if(this.data.currentTab == e.target.dataset.current){ return false; }else{ page.setData({currentTab: e.target.dataset.current}); } } })
注意size不用加像素单位px,不然识别不了size为0
该组件支持转义符’’,如 \t,\n,\f 等。text组件内只支持text嵌套,除了文本节点,其余节点都没法长按选中。
能够看出text组件至关于行内元素
<!-- percent : 百分比 默认值:0 --> <!-- show-info : 进度条右侧显示百分比 默认值:false --> <progress percent='20' show-info></progress> <!-- stroke-width : 进度条线宽(高?) 默认值:6 --> <progress percent='40' stroke-width='12'></progress> <!-- color : 进度条颜色 默认值:#09BB07 --> <progress percent='60' color='pink'></progress> <!-- active : 进度条从左往右出现动画 默认值:false --> <progress percent='80' active></progress>
view{background-color: yellow; }
2. checkbox多项选择器
3. radio单项选择器
纠正: 上面的checkbox和radio都是自闭合标签,在输入的时候开发工具的智能提示补全成双标签,这点没有注意到,可是可以正常显示,不知道是否非自闭合才是官方写法呢?
<!--pages/message/message.wxml--> <!-- focus:获取焦点 默认值:false --> <view class='section'> 点击聚焦:<input placeholder='只有在单击下方按钮时才聚焦' focus='{{ focus }}' /> <view class='btn-area'> <button bindtap='tapToFocus'>点我获取焦点</button> </view> </view> <!-- password:是不是密码类型 默认值:false--> <view class='section'> 密码:<input type='number' value='123456' password placeholder='不带小数点的数字键盘'/> </view> <!-- type:input的类型,有效值有:text, number, idcard, digit 默认值:text--> <view class='section'> <input type='digit' placeholder='带小数点的数字键盘'/> </view> <!-- placeholder-style:指定placeholder的样式 --> <view class='section'> <input type='idcard' placeholder='身份证输入键盘(数字键盘,不带小数点,有个x键)' placeholder-style='color:pink'/> </view> <!-- placeholder-class:指定placeholder的样式类 --> <!-- maxlength:最大输入长度,默认值140. 设置为-1不限制最大长度 --> <view class='section'> <input maxlength='10' placeholder='最大输入长度10' placeholder-class='plred'/> </view> <!-- bindinput:键盘输入时触发input事件,处理函数能够直接return一个字符串,将替换输入框中的内容 --> <view class='section'> <input bindinput='bindKeyInput' placeholder='输入同步到view中'/> 您输入的是:{{ inputvalue }} </view> <view class='section'> <input bindinput='bindReplaceInput' placeholder='连续两个1变成2'/> </view> <view class='section'> <input bindinput='bindHideKeyboard' placeholder='输入123收起键盘'/> </view> <!-- 除了bindinput还有bindfocus , bindblur, bindconfirm 分别对应得到焦点,失去焦点,单击“完成”按钮时触发的事件 -->
/* pages/message/message.wxss */ .section{ margin-top: 10px; padding: 0 20px; } input{ border: 1px solid #ccc; } .plred{ color: red; }
// pages/message/message.js Page({ data: { focus: false, inputvalue: '' }, tapToFocus: function(){ this.setData({ focus:true }); }, bindKeyInput: function(e){ this.setData({ inputvalue: e.detail.value }); }, bindReplaceInput: function(e){ var value = e.detail.value; var pos = e.detail.cursor; if(pos != -1){ //光标在中间 var left = e.detail.value.slice(0,pos); //计算光标的位置 pos = left.replace(/11/g,'2').length;; } //直接返回对象,能够对输入进行过滤处理,同时能够控制光标的位置 return { value: value.replace(/11/g,'2'), cursor: pos } //或者直接返回字符串,光标在最后 //return value.replace(/11/g,'2'); }, bindHideKeyboard: function(e){ if(e.detail.value === '123'){ //收起键盘 wx.hideKeyboard(); } } })
效果图:
input组件是一个native组件,字体是系统字体,因此没法设置font-family。
默认input输入框没有边框。
<view class='section fixed'> <!-- 若是 textarea 是在一个 position:fixed 的区域,须要显示指定属性 fixed 为 true。默认值:false --> <textarea fixed="true"></textarea> </view> <view class='section'> <!-- 输入框行数变化时调用, event.detail = {height:0,heightRpx:0, lineCount:0} --> <textarea bindlinechange='lineChange'></textarea> </view> <view class='section'> <!-- auto-height 是否自动增长行高。 设置了该属性css的height无效. 默认值false --> <textarea auto-height placeholder='自动变高'></textarea> </view>
.section{ margin-top: 150px; } textarea{ border: 1px solid #999; padding: 3px 8px; } .fixed{ position: fixed; top: 50px; left: 0; } .fixed textarea{ background-color: #ccc; }
注意: 属性的填写,fixed默认是 false的,可是若是有业务须要变更状态(某状态要false,某状态要true),则须要添加绑定,直接写false会默认转化为true。
<!--pages/message/message.wxml--> <label> <view>点我</view> <button bindtap='clickBtn' hidden>我是button</button> <checkbox-group bindchange = "checkboxChange"> <checkbox value='USA' />美国 <checkbox value='CHN' />中国 </checkbox-group> <radio-group bindchange="radioChange"> <radio value='woman' />女人 <radio value='man' />男人 </radio-group> </label>
// pages/message/message.js Page({})函数内 clickBtn: function(){ console.log("单击了button按钮"); }, checkboxChange: function(){ console.log("单击了checkbox多项选择器"); }, radioChange: function(){ console.log("单击了radio单项选择器"); },
单击label组件触发包含的第一个控件的事件,不管是否隐藏。亦可以使label的for属性绑定组件的id,便可触发对应组件的事件,不管是否包含。
<!-- range:类型能够是array也能够是objectArray,对mode为selector的选择器有效。默认值:[] --> <!-- range-key:range为objectArray时,经过range-key来指定Object中key的值做为选择器显示内容 --> <!-- value: 表示选择了range中的第几个(下标从0开始) 默认值:0 --> <!-- bindchange:value改变时触发bindchange事件,event.detail = {value:value} --> <!-- disabled:是否禁用 默认值:false --> <view class='section'> <view class='section_title'>地区选择器1</view> <picker bindchange='pickerChange' value='{{ value }}' range='{{ array }}'> <a class='picker' href="javascript:;">点击选择</a> </picker> <view > 当前选择:{{ array[index] }} </view> </view> <view class='section'> <view class='section_title'>地区选择器2</view> <picker bindchange='pickerChange' value='{{ value }}' range='{{ objectArray }}' range-key='name'> <a class='picker' href="javascript:;">点击选择</a> </picker> <view > 当前选择:{{ objectArray[index].name }} </view> </view>
.section{ margin-top: 50px; } .picker{ padding: 3px 8px; background: #ff9000; border-radius: 50px; font-weight: bold; color: white; margin: 50px 110px; }
Page({ data: { index: 0, array: ['广州','深圳','佛山','东莞','肇庆','珠海','清远'], objectArray: [ { id: 0, name: '广州' }, { id: 1, name: '深圳' }, { id: 2, name: '佛山' }, { id: 3, name: '东莞' }, { id: 4, name: '肇庆' }, { id: 5, name: '珠海' }, { id: 6, name: '清远' }, ] }, pickerChange: function(e){ console.log("picker发生了改变,新值为:"+ e.detail.value); this.setData({ index: e.detail.value }); } })
(2)时间选择器 model=“time”
value:表示选中的时间,格式hh:mm 类型String
start:有效时间范围的开始,格式hh:mm 类型String 没法选择早于start的时间
end:有效时间范围的结束,格式hh:mm 类型String 没法选择晚于end的时间
bindchange:value值发生改变时触发 event.detail={value:value}
<!-- value:表示选中的时间,格式hh:mm 类型String --> <!-- start:有效时间范围的开始,格式hh:mm 类型String 没法选择早于start的时间 --> <!-- end:有效时间范围的结束,格式hh:mm 类型String 没法选择晚于end的时间 --> <!-- bindchange:value值发生改变时触发 event.detail={value:value} --> <view class='section'> <view class='section_title'>时间选择器</view> <picker mode="time" value='{{ time }}' start="09:01" end="21:01" bindchange='timeChange' class="picker"> 选择时间 </picker> <view>当前选择:{{ time }}</view> </view>
Page({ data: { time: '12:01' }, timeChange: function(e){ this.setData({ time: e.detail.value }); }, })
(3)日期选择器 model="date’
value:表示选中的日期,格式YYYY-MM-DD 类型String -->
start:有效日期范围的开始,格式YYYY-MM-DD 类型String 没法选择早于start的时间 -->
end:有效日期范围的结束,格式YYYY-MM-DD 类型String 没法选择晚于end的时间 -->
bindchange:value值发生改变时触发 event.detail={value:value} -->
fileds:有效值year,month,day 表示选择器的粒度 默认值:day -->
disabled:是否禁用 默认值:false -->
<!-- value:表示选中的日期,格式YYYY-MM-DD 类型String --> <!-- start:有效日期范围的开始,格式YYYY-MM-DD 类型String 没法选择早于start的时间 --> <!-- end:有效日期范围的结束,格式YYYY-MM-DD 类型String 没法选择晚于end的时间 --> <!-- bindchange:value值发生改变时触发 event.detail={value:value} --> <!-- fileds:有效值year,month,day 表示选择器的粒度 默认值:day --> <!-- disabled:是否禁用 默认值:false --> <view class='section'> <view class='section_title'>日期选择器</view> <picker mode="date" value='{{ date }}' start="2014-09-01" end="2019-01-05" bindchange='dateChange' class="picker"> 选择日期 </picker> <view>当前选择:{{ date }}</view> </view>
Page({ data: { date: '2019-01-05' }, timeChange: function(e){ this.setData({ date: e.detail.value }); }, })
(4)picker-view 嵌入页面滚动选择器
picker-view 嵌入页面滚动选择器只有picker-view-column组件。
<!--pages/message/message.wxml--> <!-- value:类型是数组,分别表示picker-view-column选择的第几项(下标从0开始),数字大于可选长度时选择最后一项 --> <!-- indicator-style:设置选择器中间选中框的样式 --> <!-- bindchange:value值改变时触发,event.detail={value:value}。value为数组,表示picker-view-column当前选择的是第几项(下标从0开始) --> <view> <view style='text-align:center'>{{ year }}年{{ month }}月{{ day }}日</view> <picker-view indicator-style='height:40px' style='width:100%;height:200px;' value="{{ value }}" bindchange="pickerChange"> <picker-view-column> <view wx:for="{{ years }}" style='line-height:40px'>{{ item }}年</view> </picker-view-column> <picker-view-column> <view wx:for="{{ months }}" style='line-height:40px'>{{ item }}月</view> </picker-view-column> <picker-view-column> <view wx:for="{{ days }}" style='line-height:40px'>{{ item }}日</view> </picker-view-column> </picker-view> </view>
// pages/message/message.js const date = new Date(); const years = []; const months = []; const days = []; for(let i = 1990;i <= date.getFullYear(); i++){ years.push(i); } for(let i = 1; i <= 12; i++){ months.push(i); } for (let i = 1; i <= 31; i++) { days.push(i); } Page({ data: { years: years, year: date.getFullYear(), months: months, month: date.getMonth()+1, days: days, day: date.getDate(), value: [999,0,1] }, pickerChange: function(e){ const val = e.detail.value; this.setData({ year: this.data.years[val[0]], month: this.data.months[val[1]], day: this.data.days[val[2]] }); }, })
<view class='section'> <view class='section_title'>slider滑动选择器</view> <view class='view-body'> <!-- min:最小值,默认值为0 --> <!-- max:最大值,默认值为100 --> <!-- step:步长,取值必须大于0且能够被(max-min)整除,默认值为1 --> <!-- value:当前取值,默认值为0 --> <!-- show-value:是否显示当前value,默认值为false --> <!-- block-size:设置滑块大小 --> <!-- activeColor:滑动区域颜色,默认值为#1aad19 --> <!-- backgroundColor:未滑动区域颜色,默认值为#e9e9e9 --> <!-- bindchange:完成一次拖动后出发,event.detail = {value:value} --> <slider min='50' max='200' step='5' block-size='40' activeColor="#1aad19" backgroundColor='red' bindchange='sliderChange' show-value></slider> <slider></slider> </view> </view>
Page({ sliderChange: function(e){ console.log("当前值:"+ e.detail.value); }, })
<view class='switch'> <view class="section"> <view>接收新消息通知</view> <switch type='switch' checked></switch> </view> <view class="section"> <view>通知显示消息详情</view> <switch type='switch' color='red'></switch> </view> <view style='height:30px'></view> <view class="section"> <view>声音</view> <switch type='checkbox' checked></switch> </view> <view class="section"> <view>震动</view> <switch type='checkbox' bindchange='switchChange'></switch> </view> </view>
.switch{ background-color: #ccc; padding-top: 10px; } .switch .section{ display: flex; justify-content: space-between; background-color: #fff; }
Page({ switchChange: function(e){ //返回true或者false console.log("是否选中:"+ e.detail.value); }, })
<view class='mt15'> <form bindsubmit='formSubmit' bindreset='formReset'> <view class='mt15 fwb'>switch开关选择器</view> <switch name='switch' /> <view class='mt15 fwb'>input单行输入框</view> <input name='input' placeholder='please input here' /> <view class='mt15 fwb'>slider滑动选择器</view> <slider name='slider' show-value></slider> <view class='mt15 fwb'>radio单项选择器</view> <radio-group name='radio'> <label><radio value=' man' />男</label> <label><radio value='woman' />女</label> </radio-group> <view class='mt15 fwb'>checkbox多项选择器</view> <checkbox-group name='checkbox'> <label><checkbox value='1' />A</label> <label><checkbox value='2' />B</label> <label><checkbox value='3' />C</label> <label><checkbox value='4' />D</label> </checkbox-group> <view class='mt15 fwb'>picker滚动选择器</view> <picker name='picker' mode='time' value='{{ time_value }}' start="09:01" end="23:01">{{ time_value }}</picker> <view class='btn-area'> <button formType='submit' type='submit'>Submit</button> <button formType='reset' >Reset</button> </view> </form> </view>
.mt15{ margin-top: 15px; } .fwb{ font-weight: bold; }
Page({ data: { time_value: '22:13' }, sliderChange: function(e){ console.log("当前值:"+ e.detail.value); }, switchChange: function(e){ console.log("是否选中:"+ e.detail.value); }, formSubmit: function(e){ console.log(e.detail.value); console.log("input的值为:" + e.detail.value.input); }, formReset: function(){ console.log("表单重置了!"); }, });
云开发测试环境与正式环境
设置 --> 暂停服务设置 --> 暂停服务
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/event.html
https://www.imooc.com/article/40838?block_id=tuijian_wz ---------未完待续-------------