微信小程序基础

什么是微信小程序

  1. 微信小程序是一种不需下载安装便可使用的应用,他实现了应用“触手可及”的梦想。
  2. 用户扫一扫或者搜一下便可打开应用,也提现了“用完即走”的理念。
  3. 用户不用关心是否安装太多应用的问题,应用将无处不在又随时可用,但又“无需安装卸载”。
  4. 微信上才能使用

微信小程序和原生App的比较

功能方面,小程序应该比原生App更单一;
设计方面,小程序应该比原生App更简洁;
使用场景方面,小程序比原生App更明确。
(微信小程序应该聚焦某个功能点,成为随时解决用户单一需求的工具)javascript

微信公众平台接口测试账号申请

注意:一个邮箱对应一个公众号或小程序。css

  1. 注册帐号
    注册帐号类型为:小程序
    注册邮箱不能是微信开放平台注册过的邮箱,也不能是我的微信号绑定的邮箱。
    小程序注册页面-3119835789
  2. 邮箱激活
  3. 信息登记
    在这里插入图片描述
    ps: 主体类型为企业时注册方式有"小额转帐"和"微信认证",一般状况下这两个操做起来都既不方便,又耗时.这时候可使用小程序复用公众号资质快速认证

条件:
1.可快速认证的小程序:企业、媒体、政府和其余组织类型的小程序;
2.要求公众号必须先完成微信认证;
3.公众号与小程序关联,且主体相同。
申请入口:
登陆公众号->小程序->小程序管理->关联小程序 -> 添加
登陆公众号->小程序->小程序管理->关联小程序 ->选中相关小程序(详情)->申请
在这里插入图片描述html

详情见: http://kf.qq.com/faq/170427FvEZNN170427YJjiAJ.htmlvue

  1. 登陆小程序管理后台
    小程序管理后台界面
  2. 完善小程序信息
    选择适合本身的服务类目,后期也能够添加服务类目,一个小程序能够添加五个服务类目。
  3. 绑定开发者

小程序代码结构

接下来就能够下载微信开发者工具来建立小程序了,AppId能够在小程序管理后台“设置”–“开发设置”中查看。
代码结构java

  • App.json小程序公共设置
    App.json能够对5个都能进行设置: 设置配置路径、配置窗口表现、配置标签导航、配置网络超时、配置debug模式
    在这里插入图片描述
  1. 配置页面路径
    pages页面路径是进行页面访问的必要条件,若是没有配置页面访问路径,页面被访问时会报错,若是定义了,则微信小程序开发工具会自动建立对应文件夹以及文件。

通常只用于建立pages目录下的文件夹(页面代码文件夹)web

  1. 配置窗口表现
    在这里插入图片描述
  2. 配置标签导航
    在这里插入图片描述
  3. 配置网络超时
    配置网络请求、文件上传、文件下载时最大的请求时间,超过这个时间将再也不请求。
    在这里插入图片描述
    在这里插入图片描述
  • App.wxss小程序公共样式表
    App.wxss是默认的全局样式文件,对CSS样式进行了扩展,和CSS使用方式同样。注意有一些CSS样式在这里是不起做用的。

与 CSS 相比,WXSS 扩展的特性有:尺寸单位 样式导入
详情见:https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxss.htmljson

  • 工具类文件(utils/util.js)
    utils文件夹下用来存放工具栏的js函数,如能够放置一些日期格式化的函数。定义完函数后要使用module.exports将定义的函数名称注册进来,在其余页面才可使用。
    util.js文件的js旨在本文件以内有效,当其余子页面想调用其中的js方法或者变量时,须要两步骤:
    ①在utils.js文件中,面向对象的方式模型输出: module.exports={要调用的函数名称:要调用的函数名称 };
    ②在要调用util.js的js文件中模块化引入utils的js文件 var object=require(“utils被调用的js文件地址”); 能够输出一下object就能看到被调用的方法了;

在这里插入图片描述
在这里插入图片描述

App()函数注册程序

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);
  1. App()函数必须在App.js中注册,且不能注册多个
  2. 不要在App()函数内使用getApp(),使用this就能够拿到App实例。

Page()函数注册页面

在每一个页面文件夹的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获取实例访问.
  }
})

page()中的设值函数setData()

该函数接收一个对象参数,用于将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等双向数据绑定框架一致,{{ }}差值表达式内能够进行一些三元运算、数学运算、逻辑判断、路径运算等简单的运算。

条件渲染 wx:if

在这里插入图片描述

  1. 能够看到,当条件不知足时,页面结构不会被渲染。(这里咱们在index.js的data里定义sex: ‘男’
  2. 对于须要一次性判断多个组件,咱们可使用 block 标签进行包裹。
    在这里插入图片描述
<!-- 这里block的wx:if下面的写法都是错的,不能正确渲染。缘由嘛,如今还不了解 -->
<block wx:if= {{ true }} >  <!-- 报错 -->
<block wx:if= "true" >  <!-- 不论是true仍是false 都是至关于true-->
<block wx:if=  true >  <!-- 不论是true仍是false 都是至关于true -->

注意,block标签并非一个组件,仅仅是一个包装元素,不会再页面中作任何渲染,只接受控制属性。

列表循环 wx:for

在组件上使用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:for指定惟一标识符 wx:key

若是表中项目位置会动态改变或者有新的项目添加到列表中,而且但愿列表中的项目保持本身的特征和状态,须要指定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位置。
在这里插入图片描述
在这里插入图片描述

scroll-view可滚动视图区域

  1. 横向滚动
<!--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

swiper滑块视图

<!--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});
    }
  }
  })

在这里插入图片描述

基础内容组件

1. icon图标组件

在这里插入图片描述

注意size不用加像素单位px,不然识别不了size为0

2. text文本组件

该组件支持转义符’’,如 \t,\n,\f 等。text组件内只支持text嵌套除了文本节点,其余节点都没法长按选中
在这里插入图片描述

能够看出text组件至关于行内元素

3. progress进度条组件

<!-- 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>

在这里插入图片描述

表单组件

  1. button
    这里指定了
view{background-color: yellow; }

在这里插入图片描述
2. checkbox多项选择器
在这里插入图片描述
在这里插入图片描述
3. radio单项选择器
在这里插入图片描述
在这里插入图片描述

纠正: 上面的checkbox和radio都是自闭合标签,在输入的时候开发工具的智能提示补全成双标签,这点没有注意到,可是可以正常显示,不知道是否非自闭合才是官方写法呢?

  1. input单行输入框
<!--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输入框没有边框。

  1. textarea 多行输入框
    这是一个与input单行输入框相对应的组件,属性与input类似。除了type和password属性,其余value, placeholder, placeholder-style, placeholder-class, disabled, maxlength, cursor-spacing, focus, bindinput, bindfocus, bindblur, bindconfirm与input单行输入框用法一致(bindinput除外,其不能将返回值反映到textarea上)
<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。

  1. label组件
    用于绑定表单元素,目前能够绑定的有 button , checkbox ,radio , switch等组件。它只有一个属性for用于绑定id。
    == label包住元素 ==
<!--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,便可触发对应组件的事件,不管是否包含。

在这里插入图片描述

  1. picker滚动选择器(普通选择器、时间选择器、日期选择器)
    (1)普通选择器 model=“selector” 默认值
    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
<!-- 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]]
    });
  },
})

在这里插入图片描述

  1. silder滑动选择器
<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);
  },
})

在这里插入图片描述

  1. switch 开关选择器
    switch开关选择器只有两个状态:开和关。
    checked: 是否选中,默认值false
    type: 样式,有效值switch,checkbox
    color: 选中时的颜色
    bindchange: checked改变时触发,event.detail={value,checked}
<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);
  },
})

在这里插入图片描述

  1. form表单
    form表单能够提交switch input checkbox slider radio picker这些组件的value值,表单组件须要加上name做为key。
<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("表单重置了!");
  },
});

在这里插入图片描述

云开发测试环境与正式环境
在这里插入图片描述
在这里插入图片描述

暂停服务

设置 --> 暂停服务设置 --> 暂停服务
在这里插入图片描述
在这里插入图片描述

一些调试报错记录。

  1. 代码没有问题,报错Error,提示是个已删除文件。
    出现该问题是因为你删除掉的文件还处于编辑状态,这时候关闭编辑器里的已删除文件窗口便可。

https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/event.html

https://www.imooc.com/article/40838?block_id=tuijian_wz ---------未完待续-------------