功能方面,小程序应该比原生App更单一;
设计方面,小程序应该比原生App更简洁;
使用场景方面,小程序比原生App更明确。
(微信小程序应该聚焦某个功能点,成为随时解决用户单一需求的工具)
注意:一个邮箱对应一个公众号或小程序。
注册账号
注册账号类型为:小程序
注册邮箱不能是微信开放平台注册过的邮箱,也不能是个人微信号绑定的邮箱。
ps: 邮箱账号不够用怎么办?
gmail邮箱设置无限账号方法(需要梯子登录gmail)
首先你需要注册一个原始账号[email protected],然后可以通过下面方式创建各种账号
用户名之间加“.”
很简单,在[email protected]的@前的账号之间,随意加入“.”都能登录成功,去其他需要注册的网站也可以使用,
因为Gmail的用户名是不区分“.”符号的,所以其实都是同一个用户名,但是创建出的用户是不同的
用户名后面加“+”
这个方法基本就能创建出无数了邮箱账号了,
[email protected],[email protected],。。。。。。,[email protected],
因为许多网站注册时候,并不识别邮箱地址中的“+”,会提示你邮箱错误。
把后缀变为http://googlemail.com
例如[email protected]
邮箱激活
信息登记
ps: 主体类型为企业时注册方式有"小额转账"和"微信认证",通常情况下这两个操作起来都既不方便,又耗时.这时候可以使用小程序复用公众号资质快速认证
条件:
1.可快速认证的小程序:企业、媒体、政府和其他组织类型的小程序;
2.要求公众号必须先完成微信认证;
3.公众号与小程序关联,且主体相同。
申请入口:
登录公众号->小程序->小程序管理->关联小程序 -> 添加
登录公众号->小程序->小程序管理->关联小程序 ->选中相关小程序(详情)->申请
详情见: http://kf.qq.com/faq/170427FvEZNN170427YJjiAJ.html
接下来就可以下载微信开发者工具来创建小程序了,AppId可以在小程序管理后台“设置”–“开发设置”中查看。
生命周期函数官方教程:https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/page.html
一般只用于创建pages目录下的文件夹(页面代码文件夹)
与 CSS 相比,WXSS 扩展的特性有:尺寸单位 样式导入
详情见:https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxss.html
App.js的App()函数内不仅可以定义全局函数和数据,还可以指定小程序的生命周期函数。
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及 中的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对应的值改变成对象参数的值。注意,该方法也可用于添加数据。
<view>{{ text }}view>
<button bindtap='changeText'>Change normal databutton>
<view>{{ array[0].text }}view>
<button bindtap='changeTextInArray'>Change array databutton>
<view>{{ object.text }}view>
<button bindtap='changeTextInObject'>Change object databutton>
<view>{{ newData.text }}view>
<button bindtap='addNewData'>Add new databutton>
// 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'
})
},
wxml中的动态数据来自js文件中的Page的data。通过双花括号{{ }}进行绑定。在需要绑定的任意位置{{ data }}写入,即绑定数据的地方都需要{{ }},这点和vue不同。同样,和vue等双向数据绑定框架一致,{{ }}差值表达式内可以进行一些三元运算、数学运算、逻辑判断、路径运算等简单的运算。
注意,block标签并不是一个组件,仅仅是一个包装元素,不会再页面中做任何渲染,只接受控制属性。
在组件上使用wx:for控制属性绑定一个数组,即可使用数组中的各项数据重复渲染该组件。
举个栗子,
首先js中定义个对象数组:
// pages/index/index.js
Page({
data: {
array: [{name: '小明'},{name: '小红'},{name: '小白'}]
}
})
然后定义页面结构:
<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来渲染多个组件。
<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:发现这里使用模板的时候可以写成自闭和标签
<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位置。
<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;
}
<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 viewbutton>
<button type='default' bindtap="tapMove">click me to scrollbutton>
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
<view class='header'>
<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滑块的页签切换效果实现多种类别方式切换
<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组件相当于行内元素
<progress percent='20' show-info>progress>
<progress percent='40' stroke-width='12'>progress>
<progress percent='60' color='pink'>progress>
<progress percent='80' active>progress>
view{background-color: yellow; }
2. checkbox多项选择器
要想在表单提交时获取到chckbox
的值,需要在checkbox-group
标签里面加上name属性。
纠正: 上面的checkbox和radio都是自闭合标签,在输入的时候开发工具的智能提示补全成双标签,这点没有注意到,但是能够正常显示,不知道是否非自闭合才是官方写法呢?
<view class='section'>
点击聚焦:<input placeholder='只有在单击下方按钮时才聚焦' focus='{{ focus }}' />
<view class='btn-area'>
<button bindtap='tapToFocus'>点我获取焦点button>
view>
view>
<view class='section'>
密码:<input type='number' value='123456' password placeholder='不带小数点的数字键盘'/>
view>
<view class='section'>
<input type='digit' placeholder='带小数点的数字键盘'/>
view>
<view class='section'>
<input type='idcard' placeholder='身份证输入键盘(数字键盘,不带小数点,有个x键)' placeholder-style='color:pink'/>
view>
<view class='section'>
<input maxlength='10' placeholder='最大输入长度10' placeholder-class='plred'/>
view>
<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>
/* 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 fixed="true">textarea>
view>
<view class='section'>
<textarea bindlinechange='lineChange'>textarea>
view>
<view class='section'>
<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。
<label>
<view>点我view>
<button bindtap='clickBtn' hidden>我是buttonbutton>
<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,即可触发对应组件的事件,无论是否包含。
<view class='section'>
<view class='section_title'>地区选择器1view>
<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'>地区选择器2view>
<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}
<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 -->
<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组件。
<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'>
<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' />Alabel>
<label><checkbox value='2' />Blabel>
<label><checkbox value='3' />Clabel>
<label><checkbox value='4' />Dlabel>
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'>Submitbutton>
<button formType='reset' >Resetbutton>
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
参考:https://segmentfault.com/a/1190000008875029
但是我这里遇到这个和执行时间过长没有任何关系,代码并没有执行时间过长的逻辑。最后发现重启微信开发者工具就可以了,不知道是不是因为开启了服务端口开发的原因。
文件预览 https://fatesinger.com/100293
ios可以直接用web-view预览,安卓需要本地预览
wx.getSystemInfo({
success: function (res) {
that.setData({
systemInfo: res
});
}
})
// 安卓
wx.downloadFile({
url: pdfUrl,
success: function (res) {
console.log(res)
var Path = res.tempFilePath //返回的文件临时地址,用于后面打开本地预览所用
wx.openDocument({
filePath: Path,
success: function (res) {
console.log('打开成功');
}
})
},
fail: function (res) {
console.log(res);
}
})
设置单个页面的下拉刷新
在页面的json文件中配置(需要注意的写在对象的最上层,而不是像app.json写在window对象下):
"backgroundTextStyle": "#222",
"enablePullDownRefresh": true,
这里遇到的问题就是不理解设置背景色和app.json
中用backgroundColor
不一样,而是用backgroundTextStyle
,不理解,记录下。
---------未完待续-------------