微信小程序开发——零基础学习(2)

116 阅读9分钟

今天接着上次的学习

1.app.js中的生命周期函数与globalData

1.1 案例展示

image.png 打印出相关信息

App({

  /**
   * 进入--小程序初始化完成时,会触发 onLaunch(全局只触发一次)
   */
  onLaunch: function () {
  console.log("初始化了项目");
  this.globalData.name='小刘'
  /*通过this可以拿到globalData对象 ,其中on开头的函数都是同一级的*/
  },

  /**
   * 当小程序启动,或从后台进入前台显示,会触发 onShow
   */
  onShow: function (options) {
  console.log("onShow触发了")
  },

  /**
   * 当小程序从前台进入后台,会触发 onHide
   */
  onHide: function () {
    console.log("onHide触发了")
  },

  /**
   * 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息
   */
  onError: function (msg) {
    
  },
  globalData:{
    name:"weixin"
  }
})

App({

  /**
   * 进入--小程序初始化完成时,会触发 onLaunch(全局只触发一次)
   */
  onLaunch: function () {
  console.log("初始化了项目");
  this.globalData.name='小刘'
  /*通过this可以拿到globalData对象 ,其中on开头的函数都是同一级的*/
  },

  /**
   * 当小程序启动,或从后台进入前台显示,会触发 onShow
   */
  onShow: function (options) {
  console.log("onShow触发了")
  },

  /**
   * 当小程序从前台进入后台,会触发 onHide
   */
  onHide: function () {
    console.log("onHide触发了")
  },

  /**
   * 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息
   */
  onError: function (msg) {
    
  },
  globalData:{
    name:"weixin"
  }
})

2.page内的onload及data差值表达式

2.1 page内的onload

app.json进行全局定义,通过调用const app 进而打印出name的值

const app=getApp()
/*调用全局,可以拿到app这个对象,app中可以拿到globalData */
console.log(app.globalData.name)
/*在app.js里面定义了globalData.name */
Page({

  /**
   * 页面的初始数据
   */
  data: {

    
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    console.log(app.globalData.name)
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  }
})
const app=getApp();
Page({

  /**
   * 页面的初始数据
   */
  data: {
  
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    console.log("index内的onload");
    app.globalData.name="高启强"
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {
    
  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {
    
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {
    
  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {
    
  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {
    
  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {
    
  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {
    
  }
})

2.2 data差值表达式

实例展示:

image.png

“张三”2s后变为“李四”

Page({

  /**
   * 页面的初始数据
   */
  data: {
    name:"张三"
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    /*延迟2s进入 */
    setTimeout(()=>{
      /*在this.setData进行动态修改 */
      this.setData({
        name:"李四"
      })
    },2000)
    

  },
<view >我的名字是{{name}}</view>

3.data中不同数据类型渲染及if条件渲染

3.1实例展示

image.png

  /**
   * 页面的初始数据
   */
  data: {
    name:"张三",
    age:18,
    bool:true,
    books:["孙子兵法","红楼梦"],
    num:6,
    user:{
      name:"高启强",
      age:"50",
      gender:"男"
    }
  },

<view>
年龄:{{age}}
</view>

<view>
书籍:{{books}}
</view>

<view wx:if="{{!bool}}">
用户:{{user.name}} - {{user.gender}} - {{user.age}}
</view>

<view wx:else>
{{user.name +"-" +user.gender +"-" +user.age }}
</view>

<text wx:if="{{num ==1}}">1</text>
<text wx:elif="{{num == 2}}">2</text>
<text wx:elif="{{num == 3}}">3</text>
<text wx:elif="{{num == 4}}">4</text>
<text wx:elif="{{num == 5}}">5</text>
<text wx:else>格式错误</text>

4.for 循环列表渲染的用法

4.1 案例展示

使用 wx:for-item 可以指定数组当前元素的变量名,

使用 wx:for-index 可以指定数组当前下标的变量名:

image.png


  data: {
    article:[
      {
        id:1,
      title:"时间戳转时间格式",
      time:"2020-06-11",
      picurl:"../../static/images/flower.png"
    },
    {
      id:2,
      title:"WXS根据时间戳计算时间间隔",
      time:"2020-04-25",
      picurl:"../../static/images/flower.png"
    },
    {
      id:3,
      title:"微信小程序wxs时间戳格式化多功能转换方法",
      time:"2020-03-20",
      picurl:"../../static/images/flower.png"
    }
  ]
  },
<!--默认使用item和index-->
<view wx:for="{{books}}" wx:for-item="item" wx:for-index="idx" wx:key="idx">
书名:{{idx+1}}-{{item}}</view>

<view class="article" wx:for="{{article}}" wx:key="id">
<image src="{{item.picurl}}" mode=""></image>
<view class="title">
{{item.title}}
</view>
<text class="time">
{{item.time}}
</text>
</view>

注意:一般默认

wx:for-item="item" wx:for-index="idx"

所以可以直接使用item和idx

5.bandtap小程序中的事件触发

事件

什么是事件

  • 事件是视图层到逻辑层的通讯方式。
  • 事件可以将用户的行为反馈到逻辑层进行处理。
  • 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。
  • 事件对象可以携带额外信息,如 id, dataset, touches

5.1事件的使用方式

  • 在组件中绑定一个事件处理函数。 如bindtap,当用户点击该组件的时候会在该页面对应的Page中找到相应的事件处理函数。
<view id="tapTest" data-hi="Weixin" bindtap="tapName"> Click me! </view>

data-hi (标识符-属性)

  • 在相应的Page定义中写上相应的事件处理函数,参数是event。
Page({
  tapName: function(event) {
    console.log(event)
  }
})
  • 可以看到log出来的信息大致如下:
{
  "type":"tap",
  "timeStamp":895,
  "target": {
    "id": "tapTest",
    "dataset":  {
      "hi":"Weixin"
    }
  },
  "currentTarget":  {
    "id": "tapTest",
    "dataset": {
      "hi":"Weixin"
    }
  },
  "detail": {
    "x":53,
    "y":14
  },
  "touches":[{
    "identifier":0,
    "pageX":53,
    "pageY":14,
    "clientX":53,
    "clientY":14
  }],
  "changedTouches":[{
    "identifier":0,
    "pageX":53,
    "pageY":14,
    "clientX":53,
    "clientY":14
  }]
}

5.2使用WXS函数响应事件

基础库 2.4.4 开始支持,低版本需做兼容处理

从基础库版本2.4.4开始,支持使用WXS函数绑定事件,WXS函数接受2个参数,第一个是event,在原有的event的基础上加了event.instance对象,第二个参数是ownerInstance,和event.instance一样是一个ComponentDescriptor对象。具体使用如下:

  • 在组件中绑定和注册事件处理的WXS函数。
<wxs module="wxs" src="./test.wxs"></wxs>
<view id="tapTest" data-hi="Weixin" bindtap="{{wxs.tapName}}"> Click me! </view>
**注:绑定的WXS函数必须用{{}}括起来**
  • test.wxs文件实现tapName函数
function tapName(event, ownerInstance) {
  console.log('tap Weixin', JSON.stringify(event))
}
module.exports = {
  tapName: tapName
}

ownerInstance包含了一些方法,可以设置组件的样式和class,具体包含的方法以及为什么要用WXS函数响应事件,请点击查看详情

事件详解

事件分类

事件分为冒泡事件和非冒泡事件:

  1. 冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。
  2. 非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。

5.3案例展示

image.png

点击【点我】之后,姓名进行变换


Page({
  /**
   * 页面的初始数据
   */
  
  data: {
    name:"咸虾米",
    age:18
  },
  onClick(event){
    let {age,myname}=event.currentTarget.dataset
        /*currentTarget 事件当前正在通过的节点 */
    console.log(age);
    console.log(myname);
    this.setData({
      name:myname,
      age:age
    })
/*当属性和值是一样的时候,可以直接写其中一个 */
//  console.log(event.currentTarget.dataset);
// this.setData({
//    name:"潇潇",
//     age:20
//  })
 },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {
    
  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {
    
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {
    
  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {
    
  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {
    
  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {
    
  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {
    
  }
})


<view class="block" data-myname="张三" data-age="22" bindtap="onClick">
点我
</view>

<view class="text">姓名:{{name}} - 年龄:{{age}}</view>

.block{
  width:200rpx;
  height:200rpx;
  background: #00b26A;

}
.text{
  font-size: 60rpx;
}

6.【小案例】熟练使用事件与数据

6.1小案例

实现功能:点击的时候模块颜色发生改变,同时取出一个随机数出来

  
  data: {
    // name:"咸虾米",
    // age:18,
    num:0,
    color:"pink",
    size:400
  },
  
  /*点击了颜色快 */
  clickBox(){
    /*所取的随机数从0-1 */
  let rdm = parseInt (Math.random()*100);
  let r1 = parseInt(Math.random()*255);
  let r2 = parseInt(Math.random()*255);
  let r3 = parseInt(Math.random()*255);

  let color=`rgb(${r1},${r2},${r3})`

  let size = parseInt(Math.random()*600);
  /*进行形状限制 */
  size = size<100 ? 200: size
  console.log(size);
  this.setData({
    num:rdm,
    /*属性和值一样的情况下可以省略值 */
    color:color,
    size:size
  })
  // console.log(rdm);
  },
<view class="box" bindtap="clickBox" style="background:{{color}};width:{{size}}rpx; height:{{size}};">
随机数:{{num}}
</view>
.box{
  margin:50rpx;
  width:200rpx;
  height:200rpx;
  background:pink;
  color:#000;
  display:flex;
  justify-content: center;
  align-items:center;
}

7.表单组件button 和Input

7.1 案例展示

image.png 实现功能:对于输入的内容进行监控


  data: {
    // name:"咸虾米",
    // age:18,
    num:0,
    color:"pink",
    size:400,
    title:""
  },
  onInput(event){
    console.log(event);
    let value =event.detail.value
    this.setData({
      title:value
    })

  },
  onFocus(event){
    console.log(event)

  },
  onBlur(event){
    console.log(event)
  },
  

<view class="out">
  <input 
  class="ipt" 
  type="text"
  placeholder="请输入用户名"
  password
  maxlength="50"
  confirm-type="search"
  bindinput="onInput"
  ></input>
  
  <view >
  输入的内容是:{{title}}</view>
  <button
 size="default"
 type="primary"
 loading="{{false}}"
 open-type="getPhoneNumber"
 disabled="{{title.length}}"
 bindfocus="onFocus"
 bindblur="onBlur"
  >按钮</button>
</view>
 <!--上面title.length相当于直接是false-->
.out{
  padding:30rpx;
  border:1px solid #eee;
  margin:30rpx;
}
.out .ipt{
  background:#eee;
  margin-bottom:20rpx;
  padding:20rpx;
}

8. checkbox 多选按钮及label组件

8.1案例展示

image.png

实现功能:在点击多选按钮之后,打印出相关信息

 checkChange(event){
    console.log(event);

  }

 <textarea class="textarea"
  placeholder="请输入详细内容"
  ></textarea>

  <checkbox-group bindchange="checkChange">

 <view style="padding-bottom:20rpx; ">
  <label>
        <checkbox value="0" ></checkbox>
        <text>钓鱼</text>
  </label>
 </view>

<view  style="margin-bottom:20rpx"> 
  <label >
    <checkbox checked value="1" ></checkbox>
    <text>打游戏</text>
  </label>
</view>

<view  style="padding-bottom:20rpx"> 
  <label >
    <checkbox color="red" value="0" ></checkbox>
    <text>看书</text>
  </label>
</view>

  </checkbox-group>
.out .textarea{
  background:#eee;
  margin-bottom:20rpx;
  /* width:calc(100% - 40rpx); */
  box-sizing: border-box;
  height:220rpx;
  padding:20rpx;

}

9.【小案例】表单提交样式布局与model双向绑定以及form评论案例的实现

[如果有疑问可以参考文档](小程序框架 / 视图层 / 简易双向绑定 (qq.com))

image.png

Page({
  /**
   * 页面的初始数据
   */
  data: {
    iptValue:"",
    listArr:[
      {id:123456,title:"告诉老墨,我要吃鱼!"},
      {id:654321,title:"咖啡不用冲,迟早会成功"},
      {id:135632,title:"妻管严啊,很幸福的"}
    ]
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {

  },
  onSubmit(){
    let value =this.data.iptValue
    // console.log(this.data.iptValue);
    let arr = this.data.listArr;
    arr.push({
      /*使用时间戳 */
      id:Date.now(),
      title:value
    })
    this.setData({
      listArr:arr,
      iptValue:""
      /*最后将输入的内容进行清空 */
    })
  },

  clickClose(event){
    let {index}= event.currentTarget.dataset;
    let arr =this.data.listArr;
    arr.splice(index,1);
    /*进行元素移除 */
    // console.log(arr);
    this.setData({
      listArr:arr
    })
  },
  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  }
})
<view class="title"></view>
狂飙经典语录
  <view class="out">
  <block wx:if="{{listArr.length}}">
    <view class="list">
        <view class="row" wx:for="{{listArr}}" wx:key="id">
          <view class="text">{{index+1}}.{{item.title}}</view>
            <view class="close" bindtap="clickClose" data-index="{{index}}">
            <!--将索引值进行传递-->
            <icon type="clear" size="26"></icon>
            </view>
      </view>
      </view>

<!--item代表listArr中的每一行-->
<view class="count"> 共有{{listArr.length}}条评论</view>
</block>

<view wx:else style="text-align: center; font-size: 38rpx; color:#555; padding:20rpx 0;" >暂无语录,请添加</view>

  <view class="comment">
   <input type="text" 
   placeholder="请输入评论内容......"
   placeholder-style="color:#aaa; font-size:28rpx "
   model:value="{{iptValue}}"
   maxlength="20"
   bindconfirm="onSubmit"
     />
     <button size="mini" type="primary" disabled="{{!iptValue.length}}"    bindtap="onSubmit">发布</button>
  </view>
</view>


.title{
  font-size:50rpx;
  text-align:center;
  color:#3c3c3c;
  padding:60rpx 0 30rpx;

}
.out{
  width:690rpx;
  margin:30rpx;
  box-shadow:0 15rpx 40rpx rgba(0,0,0,1);
  border-radius:10rpx;
  padding:30rpx;
  box-sizing:border-box;
}
.out .list .row{
  padding:15rpx 0;
  border-bottom:1rpx solid #e8e8e8;
  display:flex;
  justify-content: space-between;
  align-items: center;
  font-size:34rpx;
  color:#333;  
}
.out .list .row .text{
  padding-right:10rpx;
  box-sizing:border-box;

}
.out .count{
  padding:20rpx 0;
  box-sizing:border-box;
}

.out .comment{
  display:flex;
  margin-top:20rpx;
}
/*   flex为一个非负数字n:该数字为flex-grow的值,
   flex:n;=  flex-grow:n;
              flex-shrink:1;
              flex-basis:0%;*/
.out .comment .input{
  flex:4;
  background:#f4f4f4;
  margin-right:10rpx;
  height: 100%;
  height:64rpx;
  border-radius: 8rpx;
  padding:0 20rpx;
  color:#333;
}
.out .comment button{
  flex:1;
}