微信小程序学习

396 阅读11分钟

第一天

1. 搭建编辑环境

第一步:注册账号,安装微信小程序开发者工具

第二步:新建项目,不使用云服务,选择JavaScript语言

2. 认识小程序项目的基本组成结构

pages:用来存放小程序所有的页面

utils:用来存放工具性质的模块(例如:格式化时间的自定义模块)

app.js: 小程序项目的入口文件

app.json: 小程序项目的全局配置文件

app.wxss: 小程序项目的全局样式文件

3. 小程序文件

页面中json文件

.json: 当前页面的配置文件,配置窗口的外观,表现等 会覆盖app.json中的配置

app.json 内容

image.png

pages: 用来记录当前小程序所有页面的路径

window: 全局定义小程序所有页面的背景色,文字颜色

style:全局定义小程序组件所使用的样式版本

sitemaplocation: 用来指明sitemap.json 的位置

project.config.json

是项目配置文件,用来记录对微信开发者工具所做的个性化配置

4. 认识小程序页面

新建小程序页面:app.json中加入路径

修改小程序首页:修改app.json中pages的存放路径

wxml和html区别

1. 标签名称不同

  • div,span,img,a
  • view,text,image,navigator

2. 属性节点不同

  • a-href
  • navigator-url

3. 提供了类似vue的模板语法

  • 数据绑定
  • 列表渲染
  • 条件渲染

什么是wxss

类似css

  • 新增了rpx尺寸单位
  • 提供了全局的样式和局部样式
  • 仅仅支持部分css选择器

5. 小程序的宿主环境

通信的主体

渲染层 wxml和wxss工作在渲染层

逻辑层 js脚本工作在逻辑层

通信模型

渲染层和逻辑层的通信由微信客户端进行转发

同时客户端负责与服务器之间的数据请求和数据响应

运行机制

小程序启动

  1. 下载代码包
  2. 解析app.json全局配置文件
  3. 执行app.js入口文件,调用app()创建小程序实例
  4. 渲染小程序首页
  5. 启动完成

页面渲染

  1. 加载页面的.json配置文件
  2. 加载.wxml和.wxss样式
  3. 执行页面的.js文件,调用page()创建页面

第二天

1. 常用的视图容器组件

  • view: 类似div
  • scroll-view: 可滚动的视图效果
  • swiper: 轮播图外面盒子 swiper-item:每个轮播图项目

2. view组件

flex布局

效果

image.png

wxml

<!--pages/list/list.wxml-->
<view class="container">
<view>haha</view>
<view>haha</view>
<view>haha</view>
</view>

wxss

/* pages/list/list.wxss */
.container view{
  width: 100px;
  height: 100px;
  text-align: center;
  line-height: 100px;
}
//属于父元素的第几个子元素
.container view:nth-child(1)
{
  background-color: rgb(224, 156, 156);
}
.container view:nth-child(2)
{
  background-color: rgb(189, 224, 156);
}
.container view:nth-child(3)
{
  background-color: rgb(240, 217, 183);
}
.container{
  display: flex;
  flex-direction: row;
  justify-content: space-around;
}

3.flex布局

容器的6个属性

  1. flex-direction: 设置主轴方向
  • row:从左到右
  • row-reverse: 从右到左
  • column:从上到下
  • column-reverse:从下到上
  1. flex-wrap: 设置换行方式
  • nowrap: 不换行
  • wrap:正常换行
  • wrap-reverse: 换行,第一行在下方
  1. flex-flow: 综合前面两个属性
  2. justify-content: 决定x轴排列方式
  • flex-start: 顶着左边开始排列
  • flex-end: 顶着右边开始排
  • center: 居中
  • space-between:顶着左右两边,间距一致
  • space-around:与左右两边有间距,所有间距一致

image.png

  1. align-items: 决定在y轴上的排列方式

image.png

  1. align-content属性

image.png

4. 滚动组件

  1. 采用scroll-view实现
  2. 在wxml里面设置滚动的轴,scoll-y
  3. 给scoll-view设定高度

5. swiper和swiper-item组件

wxml

<swiper class="container2">
<swiper-item><view class="item">ok1</view></swiper-item>
<swiper-item><view class="item">ok2</view></swiper-item>
<swiper-item><view class="item">ok3</view></swiper-item>
</swiper>

wxss

.container2{
  height: 150px;
  width: 100%;
  text-align: center;
  line-height: 150px;
}
//选择的是第一个swiper-item
swiper-item:nth-child(1) .item{
  background-color: rgb(98, 103, 112);
}
//选择的是第二个swiper-item
swiper-item:nth-child(2) .item{
  background-color: rgb(155, 201, 165);
}
swiper-item:nth-child(3) .item{
  background-color: rgb(157, 177, 214);
}

第三天

常见组件

button,image,navigator

button标签

<!-- button按钮 -->
<button>默认按钮</button>
<button type="primary">主色调按钮</button>
<button type="warn">警告按钮</button>
<!-- 镂空 plain -->
<button size="mini" plain>小小的按钮</button>
<button size="mini" type="primary">小主色调按钮</button>

image标签

<!-- image标签 -->
<!-- mode属性,默认是scaleToFill:不保持纵横比缩放图片,使图片宽高拉伸至刚好填满image元素 
1.图片完整显示 2. 会被拉伸的很丑哦-->
<image src="/images/QQ图片20220522090034.jpg"></image>

<!-- aspectFit 保持纵横比缩放图片,使长边刚好完全显示出来 
1. 图片完整显示 2.会留空白哦-->
<image src="/images/QQ图片20220522090034.jpg" mode="aspectFit"></image>

<!-- aspectFill 只保证短边能够刚好显示出来,
1. 图片不会完整显示 这种模式会不改变纵横比填满整个image
2. image图片的宽高不会改变-->
<image src="/images/QQ图片20220522090034.jpg" mode="aspectFill"></image>

<!-- widthFix 宽度不变,高度自适应 
1. 图片会完整显示 2. image标签的高度改变了-->
<image src="/images/QQ图片20220522090034.jpg" mode="widthFix"></image>

<!-- heightFix 高度不变,宽度自适应 
1. 图片会完整显示 2. image标签的宽度被改变了-->
<image src="/images/QQ图片20220522090034.jpg" mode="heightFix"></image>

小程序API

三大分类:

事件监听类API

  1. 以on开头 example:wx.onWindowResize 监听窗口尺寸变化的事件

同步API

  1. 以Sync结尾
  2. 同步API的执行结果,都可以通过函数返回值直接获取,如果执行出错会抛出异常 example: wx.setStorageSync('key','value')向本地存储写入内容

异步API

  1. 需要success,fail,complete接收调用的结果

example:用wx.request()发起网络数据请求,需要success回调函数接收数据

小程序语法

插值语法

  1. 动态绑定属性

与vue不一样,无论是动态绑定内容还是动态绑定属性,都需要插值语法

<image src="{{imageSrc}}" mode="widthFix"></image>
  1. 动态绑定数据

  2. 三元运算

<view>{{randomNum >=5?'随机数字大于等于5':'随机数字小于5'}}</view>
  1. 算数运算
<view>{{randomNumber* 100}}</view>

事件绑定

小程序常用事件

类型绑定方式事件描述
tapbindtap / bind:tap手指轻点
inputbindinput / bind:input输入
changebindchange / bind:change状态改变时触发

事件对象属性列表

image.png

target和currentTarget

image.png

bindtap的语法格式

wxml

<button type="primary" bindtap="btnTapHandler">点击触发事件</button>

js

  btnTapHandler(e){
    console.log(e)

  },

利用事件绑定改变data里面的数据

wxml

<view>{{count}}</view>
<button bindtap="countChange">+1</button>

js

  countChange(e){
    this.setData({
      count: this.data.count+1
    })
  },

事件传参

小程序中无法一边绑定事件一边传递参数,因为小程序的事件采用插值语法的解析方式,会误认为整体是个函数名,只能通过data_* 的方式去传递参数

wxml

<!-- 事件传参 -->
<!-- 如果不加花括号,传入的是字符串,加了花括号,传入的是数字 -->
<button type="primary" bindtap="btnTapHandler2" data-info="2">+2</button>

js

  btnTapHandler2(e){
    this.setData({
      //dataset是一个对象,保存着所有通过data-*传递过来的参数项
      count:this.data.count+e.target.dataset.info,
    })
  },

bindinput的语法格式

wxml

<input bindinput="inputHandler" value="12345"></input>

js

  inputHandler(e){
    console.log(e.detail.value)

  },

条件渲染

wxml

<!-- 条件渲染 -->
<view wx:if="{{type===1}}"></view>
<view wx:elif="{{type===2}}"></view>
<view wx:else>保密</view>

结合block标签控制多个组件的展示与隐藏

<!-- 结合block标签控制多个组件的展示与隐藏 -->
<!-- 避免渲染出一些不必要的外层盒子 -->
<block wx:if="{{true}}">
<view>abc</view>
<view>def</view>
</block>

hidden和wx:if的区别

hidden是控制样式,wx:if是动态创建和移除元素

频繁切换的时候使用hidden,如果是多个选择一个显示的时候,控制条件比较复杂,可以选择wx:if

列表渲染

wxml

<view wx:for="{{arr1}}">
索引是:{{index}}
item项是:{{item}}
</view>

改名

<view wx:for="{{arr1}}" wx:for-index="idx" wx:for-item="itemName"></view>

key

<!-- wx:key的使用 不用加花括号,建议把id当做key值 -->
<view wx:for="{{user}}" wx:key="no">
{{item.name}}
</view>

wxss

具有大部分css的特性,具有扩展:1.rpx 2. @import

rpx

是微信小程序独有的,用于解决屏幕适配的尺寸单位

rpx的实现原理 :rpx把所有屏幕在横向上分为750份

rpx与px之间的单位换算: example: 在iphone6上面,屏幕宽度为375px

750rpx = 375px

1rpx=0.5 px

样式导入

@import后跟要导入的样式表的相对路径,用;结尾

当局部样式和全局样式冲突时,根据就近原则,如果局部样式权重大于或等于全局样式的权重,才会覆盖全局的样式

小程序窗口组成部分

image.png

window节点常用配置项

image.png

tabBar

tabBar的六个组成部分

image.png

tabBar节点的配置项

image.png

每个tab的配置项

image.png

json

 "tabBar": {
    "list": [
      {
        "pagePath": "pages/list/list",
        "text": "list"
      },
      {
        "pagePath": "pages/day3Afternoon/day3Afternoon",
        "text": "学习"
      }
    ]
  },

网络数据请求

js


getInfo(){
  wx.request({
    url: 'https://www.escook.cn/api/get',
    method:'GET',
    data:{
      name:'zs',
      age:20
    },
    success:(res)=>{
      console.log(res.data)
    }
  })

},

第四天

页面导航

声明式导航

跳转至配置为tabBar的页面

使用navigator

<navigator url="/pages/day3Morning/day3Morning" open-type="switchTab">导航到学习</navigator>

跳转至没有被配置为tabBar的页面

open-type的属性可以省略不写

<navigator url="/pages/index/index" open-type="navigate">跳转至非TabBar页面</navigator>

编程式导航

调用wx.switchTab(Object obj)方法,可以跳转到tabBar页面

image.png

导航至非tabBar页面

image.png

后退导航

image.png

image.png

导航传参

声明式导航传参

image.png

页面事件

下拉刷新

wxml

<!-- 下拉刷新 -->
<view>count:{{count}}</view>
<button bindtap="addCount">点我加一</button>

js

  addCount(){
    this.setData({
      count: this.data.count+1,
    })
  },
 /**
 * 页面相关事件处理函数--监听用户下拉动作
 */
onPullDownRefresh() {
  this.setData({
    count:0
  })
  //关闭下拉刷新
  wx.stopPullDownRefresh({
    success: (res) => {},
  })

},

上拉处理

监听上拉触底

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {
    console.log("触发了上拉刷新")

  },

案例:请求各种颜色

js

//存放获取到的数据
data: {

   colorList:[],

 },
//获取各种颜色 
 getColors(){
   wx.request({
     url: 'https://applet-base-api-t.itheima.net/api/color',
     method:'GET',
     success:({data:res})=>{
       console.log(res);
       this.setData({
         //扩展运算符(…)作用是将一个数组转为用逗号分隔的参数序列
         colorList:[...this.data.colorList,...res.data]
       })
     },
     complete:()=>{
       wx.hideLoading()
     }
   })
 },
 //触发这个函数
onReachBottom() {
   console.log("触发了上拉刷新")
   this.getColors();
   wx.showLoading({
     title: '加载中',
   })
   

生命周期

小程序生命周期函数

  • onLaunch
  • onShow
  • onHide

页面生命周期函数

  • onLoad 监听页面加载,一个页面调用一次 ❀:初始化数据
  • onShow 监听页面显示
  • onReady 监听页面初次渲染完成,一个页面只调用一次 ❀:修改页面的样式
  • onHide 监听页面隐藏
  • onUnload 监听页面卸载

内嵌wxs代码

<view>{{m1.toUpper(name)}}</view>
<!-- 充当过滤器 -->
<wxs module="m1">
module.exports.toUpper=function(str){
return str.toUpperCase()
}
</wxs>

总结:

  • 实现页面之间导航跳转
  • 知道如何实现下拉刷新的效果
  • 知道如何实现上拉加载
  • 能够知道常用的生命周期函数

第五天

小程序组件

局部引用组件

在要引用的界面的json

{
  "usingComponents": {
    "my_test1":"/components/test/test"
  }
}

全局引用

在app.json里面注册组件

"usingComponents": {
    "my_test2":"/components/test/test"
  },

组件和页面的区别

  • 组件的.json文件中需要声明"component":true属性
  • 组件的js文件调用Component()函数
  • 组件的事件处理函数需要定义到method节点中

自定义组件的样式

app.wxss中定义的样式对组件无效,但只有class选择器会有样式隔离效果

取消样式隔离

组件js

  options:{
    styleIsolation:'apply-shared'

  },

三个选项

  • isolated 样式隔离,使用class指定的样式不会互相影响
  • apply-shared wxss会影响组件
  • shared 组件会影响页面和其他也设置了apply-shared或shared的自定义组件

事件处理函数和自定义方法

组件js

  methods: {
  //点击事件处理函数
  addCount(){
    this.setData({
      count:this.data.count+1
    })
    this._showCount()

  },
  //自定义方法
  _showCount(){
    wx.showToast({
      title: 'count是'+this.data.count,
    })
  }
}

properties属性

properties是组件的对外属性,用来接收外界传递到组件中的数据

案例:控制最大值

组件js


 properties: {
  //简化方式,无法使用默认值
  max:Number,
  //可以指定默认值
  max:{
    type:Number,
    value:10
  }
  
   addCount(){
    //控制最大值
    if(this.data.count>this.properties.max)
    return
    this.setData({
      count:this.data.count+1
    })
    this._showCount()

  },
  //自定义方法
  _showCount(){
    wx.showToast({
      title: 'count是'+this.data.count,
      icon:"none"
    })
  }

其实小程序中data和properties都是可读可写的,本质上是一样的,只是人为进行了划分

数据监听器

数据监听器: 当页面数据发生变化时,监听器可以被触发,然后执行相应的函数

数据监听器用于监听和响应任何属性和数据字段的变化,从而执行特定的操作,他的作用类似于vue中的watch监听器 案例:n1+n2=sum wxml

<view>{{n1}}+{{n2}}={{sum}}</view>
<button bindtap="n1Add">n1++</button>
<button bindtap="n2Add">n2++</button>

js

 data: {
    count:1,
    n1:0,
    n2:0,
    sum:0

  },
  //数据监听
  observers:{
    //通过监听器监听n1和n2的变化
    'n1,n2':function(n1,n2){
      this.setData({
        sum:n1+n2
      })
    }

  },

监听对象属性的变化

监听对象单个或者多个属性的变化

image.png

自定义组件-父子组件之间的通信

属性绑定

用于父向子传值,只能传递普通类型的数据,无法将方法传递给子组件 直接在子组件声明的时候将值传递进去

事件绑定

用于子组件向父组件传递数据,可以传递任意数据

  1. 在父组件的js中,定义一个函数,这个函数即将通过自定义事件的形式,传递给子组件
  2. 在父组件的wxml中,通过自定义事件的形式,将步骤1中定义的函数引用,传递给子组件
  3. 在子组件的js中,通过调用this.triggerEvent('自定义事件名称',{参数对象}),将数据发送到父组件
  4. 在父组件的js中,通过e.detail获取到子组件传递过来的数据

第一步 在父组件的js文件内声明一个函数,这个函数会传给子组件,当子组件的按钮被点击之后,父组件的函数会拿到子组件传回来的数据

  syncCount(e){
    console.log('syncCount')
    console.log(e.detail.value)
    this.setData({
      count:e.detail.value
    })
  }

第二步,通过自定义事件的形式,将这个函数传递给子组件

<zizujian1 count="{{count}}" bind:sync="syncCount"></zizujian1>

第三步,当子组件数据变化时,通过this.triggerEvent()函数,触发事件,将数据发送给子组件 可以在子组件内部通过this.triggerEvent()去调用外面父组件的函数

  methods: {
  addCount(){
    this.setData({
      count:this.properties.count+1
    })
    //触发自定义事件,将数值同步给父组件
    this.triggerEvent('sync',{value:this.properties.count})
  }
}

第四步,接收传递过来的数据

获取组件实例

  • 父组件还可以通过this.selectComponent()获取子组件实例对象

  • 这样就可以直接访问子组件的任意数据和方法

初步安装和使用vant组件库

修改vant主题样式

在app.wxss里面,写入css变量,即可对全局生效


page{
  --button-danger-background-color:#c00000;
  --button-danger-background-color:#D60000;
}

实现API promise 化

首先安装

npm i --save miniprogram-api-promise@1.0.4
import {promisifyAll} from 'miniprogram-api-promise'
const wxp=wx.p={}
promisifyAll(wx,wxp)

实现全局数据共享

全局数据共享可以解决组件之间数据共享问题 首先安装

npm i --save mobx-miniprogram@4.13.2 mobx-miniprogram-bindings@1.2.1