微信小程序笔记

一、简介

小程序与网页开发的区别

  • 运行环境不同
  • 网页运行在浏览器中,小程序运行在微信环境中
  • API不同
  • 无法调用DOM和BOM的AP,但可以调用微信的API:地理定位、扫码、支付
  • 开发模式不同
  • 网页开发模式:浏览器+代码编辑器
  • 小程序开发模式:
    • 申请小程序开发账号
    • 安装小程序开发者工具
    • 创建和配置小程序项目

二、小程序开发工具的介绍

获取AppID

https://mp.weixin.qq.com/ 中进入到开发管理-开发设置,获取到APPID

设置外观和代理

在主界面中的设置中,选择外观和代理选择“不适用任何代理”

创建小程序项目

点击项目-新建项目-输入项目名称、目录、APPID,不使用云服务,选择javaScript,即可。

在小程序中显示

在开发工具中预览:点击编辑即可。

在手机中的预览:点击预览按钮,会显示一个二维码,使用手机扫码预览。

开发工具中5个组成部分

  • 菜单栏
  • 模拟器
  • 工具栏
  • 代码编辑区
  • 调试区

项目组成结构

  • pages:用来存放所有小程序的页面
  • utils:用于存放工作性质的模块(格式化时间的自定义模块)
  • app.js:小程序项目的入库文件
  • app.json:小程序项目的全局配置文件
  • app.wxss:小程序的全局样式文件
  • project.config.json:项目的配置文件
  • sitemao.json:配置小程序及其页面是否允许被微信索引

Pages:小程序页面的组成部分

官方推荐每个页面放到一个文件夹中,如登录界面和后台界面 都单独存放

  • index:
  • index.js:页面的脚本文件,存放页面的数据、事件处理函数
  • index.json:当前页面的配置文件,配置窗口的外观、表现等
  • index.wxml:页面的模板结构文件
  • index.wxss:页面的样式表文件

JSON配置文件

作用:是一种数据格式,在开发中,JSON总是以配置文件的形式出现。

小程序中的4种json配置文件:

  • 项目根目录的 app.json配置文件
  • 项目根目录的project.config.json配置文件
  • 项目根目录的sitemap.json
  • 每个页面文件种的.json

app.json文件

小程序的全局配置,包括了小程序的页面路径、窗口外观、界面表现、底部tab等

{
  "pages":[   ##记录当前小程序所有页面的路径
    "pages/index/index",
    "pages/logs/logs"
  ],
  "window":{  ##全局定义小程序所有页面的背景色、文字颜色等
    "backgroundTextStyle":"light",
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "Weixin",
    "navigationBarTextStyle":"black"
  },
  "style": "v2", ##全局定义小程序组件所使用的版本样式  v2是最新的  使用旧的就删除就行
  "sitemapLocation": "sitemap.json" ## 用来指明sitemap.json的位置,存放路径
}
  • pages:用来记录当前小程序所有的页面的路径
  • windown:全局定义小程序所有页面的背景色、文字颜色等
  • style:全局定义小程序组件所使用的版本样式 v2是最新的 使用旧的就删除就行
  • sitemapLocation:用来指明sitemap.json的位置,存放路径。

project.config.json文件

是项目配置文件,用来记录对小程序所作的个性化配置,例如:

  • setting:保存了编译相关的配置
  • projectname:项目名称
  • appid:小程序的账号ID
{
  "description": "项目配置文件",
  "packOptions": {
    "ignore": [
      {
        "type": "file",
        "value": ".eslintrc.js"
      }
    ]
  },
  "setting": { //在详情中的本地设置
    "bundle": false,
    "userConfirmedBundleSwitch": false,
    "urlCheck": true,
    "scopeDataCheck": false,
    "coverView": true,
    "es6": true, 
    "postcss": true,
    "compileHotReLoad": true,
    "lazyloadPlaceholderEnable": false,
    "preloadBackgroundData": false,
    "minified": true,
    "autoAudits": false,
    "newFeature": false,
    "uglifyFileName": false,
    "uploadWithSourceMap": true,
    "useIsolateContext": true,
    "nodeModules": false,
    "enhance": true,
    "useMultiFrameRuntime": true,
    "useApiHook": true,
    "useApiHostProcess": true,
    "showShadowRootInWxmlPanel": true,
    "packNpmManually": false,
    "enableEngineNative": false,
    "packNpmRelationList": [],
    "minifyWXSS": true,
    "showES6CompileOption": false,
    "minifyWXML": true
  },
  "compileType": "miniprogram",
  "libVersion": "2.19.4",
  "appid": "", //微信的appID,拿别人的项目记得改
  "projectname": "wechat_demo1", //项目名称  项目名称不等于小程序名称
  "debugOptions": {
    "hidedInDevtools": []
  },
  "scripts": {},
  "staticServerOptions": {
    "baseURL": "",
    "servePath": ""
  },
  "isGameTourist": false,
  "condition": {
    "search": {
      "list": []
    },
    "conversation": {
      "list": []
    },
    "game": {
      "list": []
    },
    "plugin": {
      "list": []
    },
    "gamePlugin": {
      "list": []
    },
    "miniprogram": {
      "list": []
    }
  }
}

sitemap.json文件

现已开放小程序内搜索,类似与PC页面的SEO,sitemap.json用来配置小程序页面是否允许微信索引

{
  "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
  "rules": [{
  "action": "allow", //disallow 不允许被微信索引到
  "page": "*" //所有的项目都允许索引
  }]
}

页面的.json配置文件

小程序的每一个页面,可以使用.json文件对本页面的窗口外观进项配置,页面中的配置项会覆盖app.json的window中相同的配置

  • 在app.json中的
"window":{
    "backgroundTextStyle":"light",
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "Weixin",
    "navigationBarTextStyle":"black"
  },
  • 在某个页面中.json中,将该页面中的背景色改为蓝色
"navigationBarBackgroundColor": "#00026A"

如果某个页面中的配置和app.json中的配置冲突了,以页面中的为主

新建小程序页面

只需要在 app.json–》pages中新增页面的存放路径,小程序开发工具自动创建对应的页面文件。

  "pages":[
    "pages/index/index",
    "pages/logs/logs",
    "pages/list/list" //会自动创建一个list文件夹。创建了 pages文件夹/list文件夹/list页面
  ],

修改项目首页

只需要调整app.json–>pages数组中页面路径的前后顺序,即可修改项目的首页。工具会把排在第一位的页面,当作首页进项渲染

"pages":[
    "pages/list/list",
    "pages/index/index",
    "pages/logs/logs"
  ],

WXML模板

是小程序一套标签语言,用来构建小程序页面的结构,其作用类似于网页开发中的HTML

WXML和HTML的区别

  • 标签名称不同
  • HTML(div、span、img、a)
  • WXM(view、text、image、navigator)
  • 属性节点不同
  • HTML<#a href=”#“>超链接<# /a>
  • <#navigator url=" /pages/home/home">
  • 提供了类似与vue中的模板语法
  • 数据绑定
  • 列表渲染
  • 条件渲染

WXSS样式

是一套样式语言,用于描述WXML的组件样式,类似与CSS

WXSS和CSS的区别

  • 新增了rpx尺寸单位
  • CSS需要手动进项像素单位换算,例如rem
  • 支持新的尺寸的单位rpx,在不同大小的屏幕上自动进项换算
  • 提供了全局的样式和局部样式
  • 项目跟目录中的app.wxss会作用于所有小程序页面
  • 局部页面的.wxss样式仅对当前页面生效
  • WXSS仅支持部分CSS选择器
  • 用比较常用的css选择器
  • .class和#id
  • element
  • 并集选择器、后代选择器
  • ::after和::before等伪类选择器

JS逻辑交互

用来处理用户的操作

分类

分为三大类:

  • app.js:是整个小程序的入口文件,通过调用APP()函数来启动整个小程序
  • 页面的.js文件:是页面的入口文件,通过调用Page()函数来创建并允许页面
Page({
  data: {
    motto: 'Hello World',
    userInfo: {},
    hasUserInfo: false,
    canIUse: wx.canIUse('button.open-type.getUserInfo'),
    canIUseGetUserProfile: false,
    canIUseOpenData: wx.canIUse('open-data.type.userAvatarUrl') && wx.canIUse('open-data.type.userNickName') // 如需尝试获取用户信息可改为false
  })
  • 普通的.js文件:utils.js

宿主环境

是指程序运行所必须的依赖环境

1、通信的主题

小程序中通信的主体是渲染测和逻辑层,其中:

  • WXML模板和WXSS样式工作在渲染层
  • JS脚本工作在逻辑层

2、通信模型

通信模型分为两部分:

  • 渲染层和逻辑层之间的通信
  • 由微信客户端进项转发
  • 逻辑层和第三方服务器之间的通信
  • 由微信客户端进项转发

运行机制

小程序启动的过程

  • 把小程序的代码包下载到本地
  • 解析app.js全局配置文件
  • 执行app.js小程序入口文件,调用APP()创建小程序实例
  • 渲染小程序首页
  • 小程序启动完成

页面渲染的过程

  • 加载解析页面的.json配置文件
  • 加载页面的.wxml模板和.wxss样式
  • 执行页面的.js文件,调用Page()创建页面实例
  • 页面渲染完成

三、小程序的组件

1.视图容器

  • view
  • 普通视图区域
  • 类似于HTML的div,是一个块级元素
  • 常用来实现页面的布局效果

实现flex横向布局

页面表 .wxml

<!--pages/list/list.wxml-->
<!-- <text>pages/list/list.wxml</text> -->
<view class="container1">
<view>A</view>
<view>B</view>
<view>C</view>
</view>

样式 .wxss

/* pages/list/list.wxss */

/* 给class属性未 container1 下的view标签添加属性 */
.container1 view{  
  width: 100px; /*  高度为100px*/
  height: 100px;
  text-align: center;  /*文本居中*/
  line-height: 100px;
}

/* container1下view的子视图添加背景 */
.container1 view:nth-child(1){  /*:nth-child (n) 选择器匹配属于其父元素的第 N 个子元素*/
  background-color: green;
}
.container1 view:nth-child(2){
  background-color: lightskyblue;
}
.container1 view:nth-child(3){
  background-color: lightpink;
}

/*给container1 实现样式*/
.container1{
  display: flex;  /*样式为横向*/
  /*display:flex 是一种布局方式。它即可以应用于容器中,也可以应用于行内元素。 容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)*/
  justify-content: space-around; /*均匀排列每个元素每个元素周围分配相同的空间 */
}
  • scroll-view
  • 可滚动的视图区域
  • 常用来实现滚动列表效果

实现纵向滚动效果

<!-- scroll-y 属性:允许纵向滚动 -->
<!-- scroll-x 属性:允许横向滚动 -->
<scroll-view class="container1" scroll-y>
<view>A</view>
<view>B</view>
<view>C</view>
</scroll-view>
```css
/* pages/scroll_view/scroll_view.wxss */
.container1 view{
  width: 100px;
  height: 100px;
  line-height: 100px;
  text-align: center;
}
.container1 view:nth-child(1){
background-color: lightseagreen;
}
.container1 view:nth-child(2){
  background-color: lightskyblue;
}
.container1 view:nth-child(3){
  background-color: lightslategrey;
}
.container1{
  border: 1px solid red;
/* 给scroll-view固定高度,给了这个高度才体现了滚动,如果高度超过了view视图的高度,则不会滚动 */
  height: 100x;
  width: 100px;
}
  • swiper和swiper-item
  • 轮播图容器组件和轮播图item组件

实现轮播图效果

<!--pages/swiper/swiper.wxml-->
<!-- 轮播图实现效果组件 -->
<!-- indicator-dots 属性:显示面板指示点 -->
<swiper class="swiper-container" indicator-dots>
<!-- 第一项 -->
<swiper-item>
<view class="item">A</view>
</swiper-item>
<!-- 第二项 -->
<swiper-item>
<view class="item">B</view>
</swiper-item>
<!-- 第三项 -->
<swiper-item>
<view class="item">C</view>
</swiper-item>
</swiper>
```css
/* pages/swiper/swiper.wxss */
/* 轮播图CSS样式 */

/* 轮播图容器的高度 */
swiper-container{
  height: 150px;
}
.item{
  height: 100%;
  line-height: 150px;
  text-align: center;
}
swiper-item:nth-child(1) .item{
  background-color: gray;
}
swiper-item:nth-child(2) .item{
  background-color: lightblue;
}
swiper-item:nth-child(3) .item{
  background-color: lightgray;
}

常用属性:

  • indicator-dots 属性:显示面板指示点
  • indicator-colo color 指示点颜色
  • indicator-active-color:color 当前选中的指示点颜色
  • autoplay: Boolean类型 是否自动切换
  • interval:number 自动切换时间间隔
  • circular Boolean 是否采用衔接滑动 默认C页面不会滑动到A页面,开启后会从C页面到A页面,A页面到C页面
<swiper class="swiper-container" 
indicator-dots indicator-color="white" indicator-active-color="gray" autoplay interval="1000" circular>

</swiper>

2.基础内容

  • text
  • 文本组件
  • 类似于HTML中的span标签,是一个行内元素

通过text组件的selectable属性,实现长按选中文件内容的效果

<view>
  手机号支持长按选不中
  <text>123123123142</text>
  手机号支持长按选中
  <text selectable>123123123142</text>
</view>
  • rich-text
  • 富文本组件
  • 支持把HTML字符串渲染为WXML结构
<view>
<rich-text nodes="<h1 style='color:red;'>标题</h1>">
</rich-text>
</view>

3.表单组件

  • button
  • 按钮组件
  • 功能比HTML中的button按钮丰富
  • 通过open-type属性调用微信提供的各种功能(客服、转发、获取用户权限、获取用户信息)
<!--pages/button/button.wxml-->
<!-- type 指定按钮类型 default primary warn-->
<button>默认按钮</button>
<button type="primary">主色调按钮</button>
<button type="warn">警告按钮</button>
<!-- size=mini 按钮尺寸 -->
<button>默认按钮</button>
<button size="mini" type="primary">主色调小尺寸按钮</button>
<button size="mini" type="warn">警告小尺寸按钮</button>
<!-- plain 镂空按钮 -->
<button size="mini" plain>默认按钮</button>
<button size="mini" type="primary" plain>主色调小尺寸按钮</button>
<button size="mini" type="warn" plain>警告小尺寸按钮</button>
  • image
  • 图片组件
  • image组件默认宽度约300px、高度约240px
  • mode属性:用来指定图片的剪裁和缩放模式,常用的mode属性值:
    • scaleToFill:(默认值)缩放模式,不保持纵横缩放图片,拉伸填满image元素,两边可能会有留白
    • aspectFit:缩放模式,保持纵横缩放图片,使图片的长边能完全显示出来,完整的图片显示出来
    • aspectFill:缩放模式,只保持图片的短边完全显示出来,图片通常只在水平或垂直方向,另一方截取
    • widthFix:缩放模式,宽度不变,高度自动变化,保持原图宽高比不变
    • heightFix:缩放模式,高度不变,宽度自动变化,保持原图宽高比不变
<!--pages/image/image.wxml-->
<!-- 空白图片位置,会预留位置 -->
<image></image>
<!-- 可能会发现留白 -->
<image src="/images/test.jpg" mode="aspectFit"></image>
<!-- 会发生剪裁 -->
<image src="/images/test.jpg" mode="aspectFill"></image>
<image src="/images/test.jpg" mode="widthFix"></image>
<image src="/images/test.jpg" mode="heightFix"></image>
  • navigator
  • 页面导航组件
  • 类似于HTML中的 a 链接

4.导航组件

5.媒体组件

6.map地图组件

7.canvas画布组件

8.开发能力

9.无障碍访问

小程序的API

  • 时间监听API
  • 特点:以on开头,用来监听某些事件的触发
  • 举例:wx.onWindowResize(function callback) 监听窗口尺寸变化的事件
  • 同步API
  • 特点:以Sync结尾的API都是同步API
  • 同步API的执行结果,可以通过函数返回值直接获取,如果执行出错会抛出异常
  • 举例:wx.setStorageSync(‘key’,‘value’)向本地存储写入内容
  • 异步API
  • 特点:类似于JQuery中的$.ajax(options)函数,需要通过success、fail、complete接受调用的结果
  • 举例:wx.request()发送网络数据请求,通过success回调函数接受数据

四、模板语法

数据绑定

  • 在data中定义数据
  • 在页面对应的.js文件中,把数据定义到data对象中即可
// index.js

Page({
  // 页面的初始数据
  data: {
    info:'hello world'
  },
  // 事件处理函数
  bindViewTap() {
    wx.navigateTo({
      url: '../logs/logs'
    })
  }
})
  • 在WXML中使用数据
  • 把data中的数据绑定到页面中渲染,使用Mutache语法(双大括号)将变量包起来即可。
<view>{{info}}</view>
  • Mustache语法的应用场景

  • 动态绑定内容

  • 动态绑定属性

    Page({
    // 页面的初始数据
    data: {
      info:'hello world',
      imgSrc:'/images/test.jpg' //定义一个imgSrc的路径
    },
    })
    
    ```html
    <view>{{info}}</view>
    <image src="{{imgSrc}}"></image><!--绑定到页面中-->
    
  • 运算(三元运算、算术运算等)

    Page({
    // 页面的初始数据
    data: {
      randomNum:Math.random()*10
    },
    })
    
    ```html
    <view>{{randomNum >=5 ? '随机数字大于等于5':'随机数字小于5'}}</view>
    
  • 算数运算

randomNum1:Math.random().toFixed(2) //生成一个带两位小数的随机数,例如0.34
```html
<view>生成一个乘于100的数字{{randomNum1*100}}</view>

事件绑定

事件是渲染层到逻辑层的通讯方式。通过事件可以将用户在渲染层产生的行为,反馈到逻辑层进项业务的处理。

类似于 onclick

  • 常用的事件:

| 类型 | 绑定方式 | 事件描述 |
| —— | ———————– | ————————————— |
| tap | bindtap或bind:tap | 触摸后马上离开,类似于HTML中的click事件 |
| input | bindinput或bind:input | 文本框的输入事件 |
| change | bindchange或bind:change | 状态改变时触发 |

  • 事件对象的属性列表
  • 当事件回调触发时,会收到一个事件对象的event,详细属性

| 属性 | 类型 | 说明 |
| ————– | ——- | ———————————— |
| type | String | 事件类型 |
| timeStamp | Integer | 事件触发所经过的毫秒数 |
| target | Object | 触发事件的组件的一些属性值集合 |
| CurrentTarget | Object | 当前组件的一些属性值集合 |
| detail | Object | 额外的信息 |
| touches | Array | 触摸事件,获取触摸点信息的数组 |
| changedTouches | Array | 触摸事件,当前变化的触摸点信息的数组 |

  • target和currentTarget的区别
  • target时触发事件的源头组件
  • currentTarget:当前事件所绑定的组件
<view class="outer-view" bindtap="outerHandler">
    <button>
        按钮
    </button>
</view>

点击按钮时,点击事件以冒泡的方式向外扩散,也会触发外层view的tap事件处理器

e.target指向的是触发事件的源头组件,因此 触发的是 button组件

e.currentTarget指向的是当前正在触发事件的那个组件,因此 触发的是 绑定bindtap的view 组件

bindtap的语法格式

在小程序中,不存在HTML中的onclick鼠标点击事件,而是通过tap事件来响应用户的触摸行为

  • 通过bindtap,可以为组件绑定tap触摸事件
<button bindtap="btnTapHandler">按钮</button>
  • 在页面的.js中定义对应的事件处理函数,事件参数通过形参 event(一般简写成e)来接受。
Page({

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

  },
//不是在page中编写,跟page平级中编写
  //定义按钮事件处理函数
  btnTapHandler(e){
    console.log(e)
  }

输出的结果

changedTouches: [{…}] 
currentTarget: {id: "", offsetLeft: 96, offsetTop: 0, dataset: {…}}
detail: {x: 247, y: 34.75}
mark: {}
mut: false
target: {id: "", offsetLeft: 96, offsetTop: 0, dataset: {…}}  //触发事件的源
timeStamp: 4043
touches: [{…}]
type: "tap" //事件的类型
_userTap: true
__proto__: Object

为data中的数据赋值

通过调用this.setData(dataObject)方法,可以给页面data中的数据重新赋值

<button bindtap="btnTapHandler">点击按钮+1</button>
<view>{{count}}</view>
```js
  Page({

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

    //定义按钮事件处理函数
    btnTapHandler(e){
      this.setData({
        count: this.data.count+1
      })
    }

uniapp 使用 @click也可以

事件传参

不能在绑定事件的同时为事件处理函数传递参数

bindtap="bindHandler(123)"  //小程序会认为这是一个事件名,不会认为可以传递123这个参数

可以通过data-自定义属性传参,其中 * 代表的是参数的名字

<button bindtap="btnHandler" data-info={{2}}>事件传参</button>//如果不写{{}}会识别成字符串
  • info会被解析为参数的名字
  • 数值2会被解析为参数的值

拿到参数这个值

通过event.target.dataset.参数名,可获得具体参数的值

 data: {
      count:0
    },    
btnTap2(e){
      this.setData({
        count:this.data.count+e.target.dataset.info
      })
    },
```html
<button bindtap="btnTap2" data-info="{{2}}">按钮2</button>

bindinput的语法格式

通过input事件响应文本框的输入事件

  • 通过bindinput,可以未文本框绑定输入事件
<input bindinput="inputHandler"></input>
  • 在页面的.js中定义事件处理函数
  //input 输入框的事件处理函数
  inputHandler(e){
console.log(e.detail.value)
  },
  • 每输入一个字符,控制台就输出一句,依次输入123,控制台输入 1 12 123

文本框和data之间的数据同步

步骤:

  • 定义数据
page({
     data: {
    msg:'你好,世界'
  }
})
  • 渲染结构
<view>
<view>请输入信息,改变下框信息</view>
<input bindinput="inputHandler"></input>

<input value="{{msg}}"></input>
</view>
  • 美化样式
input{
  border:1px solid #eee;
  padding: 5px;
  margin: 5px;
  border-radius: 3px;
}
  • 绑定input事件处理函数
  //input 输入框的事件处理函数
  inputHandler(e){
    this.setData({
      msg:e.detail.value
    })
  },

条件渲染

wx:if

使用wx:if=”{{condition}}“来判断是否需要渲染该代码块

<view wx:if="{{condition}}">True</view>

也可以用wx:elif和wx:else 来添加else判断

<view wx:if="{{type===1}}">男</view>
<view wx:elif="{{type===2}}">女</view>
<view wx:else>保密</view>
结合block使用wx:if

如果要一次性控制多个组件的展示与隐藏,可使用 block 标签将多个组件包装起来,并在 block标签上使用wx:if控制。

<block wx:if="{{type===1}}">
<view>展示的时block内容</view>
<view>展示多个内容</view>
</block>

block 并不是一个组件,只是一个包裹性质的容器,不会在页面中做任何渲染

hidden条件渲染

使用 hidden=“{{condition}}“也能控制元素的显示与隐藏

```js
data{
    falg:true
}

wx:if和hidden的对比

  • 运行方式不同
  • wx:if以动态创建和移除元素的方式,控制元素的展示与隐藏
  • hidden:以切换样式的方式,控制元素的显示与隐藏
  • 使用建议
  • 频繁切换时,使用hidden
  • 控制条件复杂时,建议使用wx:if进行展示和隐藏

列表渲染

wx:for

可以根据指定的数组,循环渲染重复的组件结构

<view wx:for="{{array}}">
    索引是:{{index}} 当前是{{item}}
</view>

默认循环项的索引用index表示,当前循环用item表示

Page({

  /**
   * 页面的初始数据
   */
  data: {
    array:['苹果','华为','小米']
  }
})

结果

索引0 是苹果
索引1 是华为
索引2 是小米
手动指定索引和当前项的变量名
  • 使用wx:for-index 可以指定当前循环的索引的变量名

  • 使用wx:for-item 可以指定当前项的变量名

<text wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
索引是{{idx}},当前是{{itemName}}
</text>
wx:key的使用

类似于Vue类别渲染中的:key,小程序在实现列表渲染中,也建议为渲染出来的列表指定唯一的key值,从而提高渲染的效率

page({
    userList:[
      {id:1,name:'小红'},
      {id:2,name:'小明'},
      {id:3,name:'小刚'}
    ]  
})
```html
<view wx:for="{{userList}}" wx:key="id">{{item.name}}</view>

使用索引,使用的是默认的index

<view wx:for="{{userList}}" wx:key="index">{{item.name}}</view>

WXSS模板样式

rpx尺寸单位:用来实现屏幕适配的尺寸单位 将屏幕等分为750份(当前屏幕的750份)

  • 在较小的设备上, 1rpx代表的宽度较小
  • 在较大的设备上,1rpx代表的宽度较大

样式导入

@import的语法格式

@import后跟需要导入的外联样式表的相对路径,用 ; 表示语句结束

/* common.wxss */
.username{
  color:red
}
```css
@import "/common/common.wxss"
```html
<view wx:for="{{userList}}" wx:key="id" class="username">{{item.name}}</view>

全局样式

定义在app.wxss中的样式为全局样式,作用在每一个页面

局部样式

在页面的.wxss文件中定义的样式为局部样式,只作用与当前页面

  • 当居于样式和全局样式冲突时,采取就近原则,局部样式会覆盖全局样式
  • 局部样式的权重大于或等于全局样式的权重时,才会覆盖全局的样式
view:nth-child(1){}  权重大

全局配置

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

  • pages:记录当前小程序所有页面的存放路径
  • window:全局设置小程序窗口的外观
  • tabBar:设置小程序底部的tabBar效果
  • style:是否启用新版的组件样式

Window

"window":{
    "backgroundTextStyle":"light",  //下拉刷新时的刷新loading的样式,只有light默认为白色,dark 灰色
    "navigationBarBackgroundColor": "#fff",  //导航栏背景色 只是16进制的
    "navigationBarTitleText": "微信导航栏",  //文件导航栏文字修改
    "navigationBarTextStyle":"black",   //导航栏标题文字颜色  可选值只有 black和white
    "enablePullDownRefresh": true,  // 全局开启开启下拉刷新效果,所有页面中都会有  false 不开启
    //下栏刷新时不会自动上去,需要处理一下
    "backgroundColor": "#efefef",  //下拉刷新时的背景颜色 灰色
    "onReachBottomDistance":50  //默认为50像素,可以修改为100像素
  },

tabBar

是移动端常见的页面效果,用于实现多页面的快速切换主要分为:

  • 底部tabBar
  • 顶部tabBar

注意:

  • tabBar只能配置最少2个、最多5个tab标签
  • 渲染顶部tabBar时,不显示icon,只显示文本。

5个组件

  • backgroundColor:tabBar的背景色
  • selectdiconPath:选中时的图片路径
  • borderStyle:tabBar上边框的颜色
  • iconPath:未选中时的图片路径
  • selectedColor:tab上的文字选中时的颜色

节点的配置项

在app.json中配置

| 属性 | 类型 | 必填 | 默认值 | 描述 |
| ————— | ——– | —- | —— | ——————————- |
| position | String | 否 | bottom | tabBar的位置,请支持bottom、top |
| borderStyle | String | 否 | black | 上边框的颜色,仅支持black/white |
| color | HexColor | 否 | | 文字的默认(未选中)颜色 |
| selectedColor | HexColor | 否 | | 选中时的颜色 |
| backgroundColor | HexColor | 否 | | tabBar的背景色 |
| list | Array | 是 | | tab页签的列表,最少2个,最多5个 |

 "tabBar": {
    "list": [{
      "pagePath": "pagePath", // 页面路径,页面必须要在pages中预先定义   必填
      "text": "text", // tab上显示的文字                               必填
      "iconPath": "iconPath",  //未选中时的图片路径,当postion为top时,不显示icon
      "selectedIconPath": "selectedIconPath"  //选中时图片的路径,,为top时,不显示icon
    },
    {
      "pagePath": "pagePath", // 页面路径,页面必须要在pages中预先定义   必填
      "text": "text", // tab上显示的文字                               必填
      "iconPath": "iconPath",  //未选中时的图片路径,当postion为top时,不显示icon
      "selectedIconPath": "selectedIconPath"  //选中时图片的路径,,为top时,不显示icon
    }]//最少需要两个list页面标签
  },

页面配置

app.js中的window节点可以全局配置小程序中每个页面的窗口表现

页面级别的.json配置文件,可以实现拥有特殊的窗口表现,在页面中配置window中的属性

采用的是就近原则,最终效果以页面配置为准

常用的配置项

  {
   "navigationBarBackgroundColor": "#000000", //导航栏背景颜色
  "navigationBarTextStyle": "white", //导航栏文字的颜色
  "navigationBarTitleText": "文字内容", //导航栏标题文字
  "backgroundColor": "#ffffff", //当前窗口的背景色
  "backgroundTextStyle": "dark", //下拉loading的样式,仅支持dark/light
  "enablePullDownRefresh": "false", //是否为当前页开启下拉刷新的效果
  "onReachBottomDistance":50 //页面上拉触底时距页面底部举例,单位为px
  }

网络请求

出于安全性方面的考虑,对数据接口的限制:

  • 只能请求HTTPS类型的接口
  • 必须在接口的域名添加到信任列表中 在详情中配置-项目配置-域名信息中查看

配置request合法域名

如请求https://www.escook.cn域名的接口

配置步骤:登录微信小程序管理后台—开发—开发设置—服务器域名—修改request合法域名

注意事项:

  • 只支持https协议
  • 不能使用IP地址或localhost
  • 域名必须经过ICP备案
  • 服务器域名一个月内最多可申请5次修改

发起GET请求

调用 wx.request() 方法,可以发起GET数据请求

getInfo(){
  wx.request({
    url: 'https://www.escook.cn/api/get',
    method:'GET',
    data:{
      name:'zx',
      age:20
    },
    success:(res)=>{
      console.log(res)
    }
  })
},
```html
<button bindtap="getInfo">发起get请求</button>

发起POST请求

getInfo(){
  wx.request({
    url: 'https://www.escook.cn/api/get',
    method:'POST',
    data:{
      name:'zx',
      age:20
    },
    success:(res)=>{
      console.log(res.data) //是真实的数据
    }
  })
},

页面刚加载时请求数据

使用onLoad事件中调用获取数据的函数

 /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    //定义事件
      this.getImage()
  },
//页面刚加载时的轮播图事件请求
      getImage(){
          wx.request({})
      }

跳过request合法域名检测

后端程序员仅提供了http协议的接口,可以跳过域名检测

在详细中—》本地设置—》选中 不校验合法域名、web-view…证书

仅限在开发和调试阶段使用

跨域和Ajax的说明

跨域问题只存在于基于浏览器的WEB开发中,小程序的宿主环境不是浏览器,所以不存在跨域问题。

直接发送请求可以。

Ajax技术的核心依赖于浏览器中的XMLHttpRequest对象,小程序宿主环境是微信客户端,不能叫做发起Ajax请求,而是叫做 发起网络数据请求

案例:本地生活

视图与逻辑

页面导航

声明式导航

导航到tabBar页面

指的是:被配置为tabBar的页面

在使用组件跳转到指定的tabBar页面时,需要指定URL属性和open-type属性,其中:

  • url:要跳转的页面的地址,必须以/ 开头
  • open-type:跳转方式,必须为switchTab 不写不会跳转
<navigator url="/pages/message/message" open-type="switchTab">导航到消息页面</navigator>

导航到非tabBar页面

没有配置在json文件的tabBar页面,只是单独的新增了一个页面

在使用组件跳转到指定的tabBar页面时,需要指定URL属性和open-type属性,其中:

  • url:要跳转的页面的地址,必须以/ 开头
  • open-type:跳转方式,必须为 navigate
<anvigator url="/pages/iinfo/info" open-type="navigate">导航到info页面</navigator>

导航非tabBar页面时,open-type可以不写

后退导航

后退到上一页或多级页面,则需要指定open-type属性和delta属性:

  • open-type:值必须时nagigateBack,表示要进行后退导航
  • delta:值必须是数字,表示后退的层级
<navigator open-type="navigateBack" delta="1">返回上一页</navigator>

如果只是后退上一页,则可以省略delta属性,其默认值为 1

编程式导航

导航到tabBar页面

调用wx.switchTab(Objetc object)方法,可以跳转到tabBar页面,参数对象

| 属性 | 类型 | 是否必选 | 说明 |
| ——– | ——– | ——– | ———————————————- |
| url | string | 是 | 需要跳转的tabBar页面路径,路径后不能带参数 |
| success | function | 否 | 接口调用成功的回调函数 |
| fail | function | 否 | 接口调用失败的回调函数 |
| complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |

<button bindtap="gotoMessage">跳转到消息页面</button>
```js
//通过编程式导航,跳转到message页面
gotoMessage(){
    wx.switchTab({
        url:'/pages/message/message'
    })
}

导航到非tabBar页面

调用wx.navigateTo(Object object)方法,跳转到非tabBar页面,属性:

| 属性 | 类型 | 是否必选 | 说明 |
| ——– | ——– | ——– | ———————————————- |
| url | string | 是 | 需要跳转的tabBar页面路径,路径后不能带参数 |
| success | function | 否 | 接口调用成功的回调函数 |
| fail | function | 否 | 接口调用失败的回调函数 |
| complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |

<button bindtap="gotoInfo">跳转到info页面</button>
```js
//通过编程式导航,跳转到info页面
gotoInfo(){
    wx.navigateTo({
        url:'/pages/info/info'
    })
}

后退导航

调用wx.navigateBack(Object object)方法,返回上一级或多级页面

| 属性 | 类型 | 是否必选 | 说明 |
| ——– | ——– | ——– | ———————————————————- |
| delta | number | 是 | 返回页面数,如果delta大于现有页面数,则返回到首页,默认为1 |
| success | function | 否 | 接口调用成功的回调函数 |
| fail | function | 否 | 接口调用失败的回调函数 |
| complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |

<button bindtap="goBack">后退</button>
```js
//后退
goBack(){
    wx.navigateBack()
}
goBack(){
    wx.navigateBack({
        delta:1
    })
}

导航传参

声明式导航传参

navigator组件的url属性用来指定将要跳转的页面的路径。同时路径的后面可以携带参数:

  • 参数与路径之间使用 ? 分割
  • 参数键与参数数值用 = 相连
  • 不同参数用 & 分割
<navigator url="/pages/info/info?name=zs&age=20">跳转到info页面</navigator>

编程式导航传参

调用wx.navigateTo(Object object)方法跳转页面时,也可以携带参数

<button bindtap="gotoInfo">跳转到info页面</button>
```js
gotoInfo(){
    wx.navigateTo({
        url:'/pages/info/info?name=zs&age=20'
    })
}

在onLoad中接收导航参数

通过声明式导航传参或编程式导航传参所携带的参数,可以直接在onLoad事件中直接获取

//监听页面加载
onLoad:function(options){
    //options 就是导航传递过来的参数对象
    console.log(options)
    this.setData({
        query:options.data
    })
}
//如果要全局使用在data中声明
data:{
    query:{} //让他默认为一个空对象,等加载数据后赋值
}

页面事件

下拉刷新

在屏幕上下拉滑动操作,从而重新加载页面数据的行为

启用下拉属性

  • 全局开启下拉刷新
  • 在app.json的window节点中,将enablePullDownRefresh设置为true,不推荐
  • 局部开启下拉刷新
  • 在页面.json配置文件中,将enablePullDownRefresh设置为true

配置下拉刷新窗口的样式

在 json文件的window节点中配置。

  • backgroundColor:配置下拉刷新窗口的背景颜色
  • backgroundTextStyle:配置下拉刷新loading的样式

监听页面的下拉刷新事件

在页面的.js文件中,通过 onPullDownRefresh()函数即可监听当前页面的下拉刷新事件

onpullDownRefresh:function(){
    console.log("触发了下拉刷新")
}

案例:

点击按钮时让count值自增+1,刷新时 count变成0

<view>count的值为:{{count}}</view>
<button bindtap="countAdd">+1</button>
```js
data{
    count:0
}
//让count+1
countAdd(){
    this.setData({
        count:this.data.count+1
    })
},
onpullDownRefresh:function(){
    this.setData({
        count:0
    })
}

停止下拉刷新的效果

下拉刷新不会主动消失,需要手动关闭,调用wx.stopPullDownRefresh()可以停止当前页面的下拉刷新

//下拉刷新的事件效果
onpullDownRefresh:function(){
    this.setData({
        count:0
    })
    //调用停止下拉刷新的效果
    wx.stopPullDownRefresh()
}
```html
export default {
        data() {
            return {
            };
        },
        onPullDownRefresh() {
            this.stoppull()
        },

    methods:{
    //监听页面加载,停止下拉刷新
            stoppull(){
                uni.stopPullDownRefresh()
                this.infoList = []
                this.getInfoList()
                return uni.$showMsg('数据加载成功')
            }
}

上拉触底

在屏幕上的上拉滑动操作,从而加载更多数据的行为。

监听页面的上拉触底事件

通过onReachBottom()函数监听当前页面的上拉触底事件

//页面上拉触底事件
onReachBottom:function(){
    console.log("触发了上拉触底的事件")
}
```html
<view class="box"></view>
```css
.box{
    height: 2000rpx;
    background-color:lighblue;
}
```js
onReachBottom:function(){
    console.log("触发了上拉触底的事件")//上拉触底,会一直发起请求,需要进行处理,同一时间不允许操作
}

配置上拉触底距离

是指触发上拉触底事件时,滚动条距离页面底部的距离,默认为 50px,可以修改

可以在.json配置文件中,通过 onReachBottomDistance属性来配置上拉触底的距离

"onReachBottomDistance":150

案例

实现步骤:

  • 定义获取随机颜色的方法
  • 在页面加载时获取初始数据
  • 渲染UI结构并美化页面效果
  • 在上拉触底时调用获取随机颜色的方法
  • 添加loading提示效果
  • 对上拉触底进行节流处理

1 、定义获取随机颜色的方法

 /**
   * 页面的初始数据
   */
  data: {
    colorList:[] //随机获取颜色的列表
  },
  getColors(){//获取随机颜色的方法
    wx.request({ //发起请求,获取随机颜色值的数量
      url: 'https://www.escook.cn/api/color',
      method:'GET',
      success:({ data:res })=>{
        this.setData({
          colorList:[...this.data.colorList,...res.data]
        })
      }
    })
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    this.getColors();
  },

3、渲染UI结构并美化页面效果

<!--pages/shanglaDemo/shangla.wxml-->

<view wx:for="{{colorList}}" wx:key="index" style="background-color: rgba({{item}});" class="num-item"></view>
```css
/* pages/shanglaDemo/shangla.wxss */

.num-item{
  border: 1rpx solid #efefef;
  border-radius: 8rpx;
  line-height: 200rpx;
  margin: 15rpx;
  text-align: center;
  text-shadow: 0rpx 0rpx 5rpx #fff;
  box-shadow: 1rpx 1rpx 6rpx #aaa;
}

4、上拉触底时获取随机颜色

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

5、添加loading提示效果

官方文档中 调用 wx.showLoading(Object object)

getColors(){//获取随机颜色的方法
    //在发起请求前调用loading效果
    wx.showLoading({
      title: '数据加载中...',  // 展示loading效果
    })
    //成功调用发送请求
    wx.request({ //发起请求,获取随机颜色值的数量
      url: 'https://www.escook.cn/api/color',
      method:'GET',
      success:({ data:res })=>{
        this.setData({
          colorList:[...this.data.colorList,...res.data]
        })
      },
      //失败后 隐藏loading效果
      complete:()=>{
          wx.hideLoading({})// 隐藏 loading 效果
      }
    })

  },

6、对上拉触底进行节流处理

  • 在data中定义 isloading 节流阀
  • false表示当前没有进行任何数据请求
  • true表示当前正在进行数据请求
  • 在getColors()中修改isloading节流阀的值
  • 在刚调用getColors时将节流阀设置为true
  • 在网络请求的complete回调函数中,将节流阀重铸为true
  • 在onReachBottom中判断节流阀的值,从而对数据请求进行节流阀控制
  • 如果节流阀的值为true,则阻止当前请求
  • 如果节流阀的值为false,则发起数据请求
data: {
    colorList:[], //随机获取颜色的列表
    isloading:false
  },
  getColors(){//获取随机颜色的方法

    this.setData({
      isloading:true //正在发起上拉触底效果
    })

    //在发起请求前调用loading效果
    wx.showLoading({
      title: '数据加载中...',  // 展示loading效果
    })
    //成功调用发送请求
    wx.request({ //发起请求,获取随机颜色值的数量
      url: 'https://www.escook.cn/api/color',
      method:'GET',
      success:({ data:res })=>{
        this.setData({
          colorList:[...this.data.colorList,...res.data]
        })
      },
      //失败后 隐藏loading效果
      complete:()=>{
          wx.hideLoading({})// 隐藏 loading 效果
          this.setData({
            isloading:false
          })
      }
    })

  },



  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {
      if(this.data.isloading) return  //如果为true,不发起请求
      this.getColors()
  },

生命周期

什么是生命周期

指一个对象从创建-》运行-》销货的整个阶段,强调的是一个时间段

  • 小程序的启动,表示生命周期的开始
  • 小程序的关闭,表示生命周期的结束
  • 中间小程序运行的过程,就是小程序的生命周期

生命周期的分类

  • 应用生命周期
  • 指小程序从启动—》运行—》销毁的过程
  • 页面生命周期
  • 每个页面的加载–》渲染–》销毁的过程
  • 页面的生命周期范围较小,应用程序的生命周期范围较大
  • 小程序启动-》页面A的生命周期-》页面B的生命周期-》页面C的生命周期–》小程序结束

生命周期函数

指:小程序提供的内置函数,会伴随生命周期,自动按次序执行

作用:允许程序员在特定的时间点,执行某些特定的操作。如,页面刚加载的时候,onLoad生命周期函数中初始化页面的数据

生命周期 强调的是 时间段

生命周期函数 强调的是 时间点

生命周期函数的分类

  • 应用的生命周期函数
  • 小程序启动–》允许—》销毁期间依次调用的那些函数
  • 页面生命周期函数
  • 页面从加载–》渲染–》销毁依次调用的那些函数

应用的生命周期函数

需要在 app.js中进行生命

// app.js
App({

  /**
   * 当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
   */
  onLaunch: function () {
    console.log('onLaunch') //对小程序数据进行初始化
  },

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

  },

  /**
   * 当小程序从前台进入后台,会触发 onHide
   */
  onHide: function () {

  },

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

  }
})

页面的生命周期函数

需要在页面的.js文件中进行声明

Page({
    onLoad :function(options)(), //监听页面加载,一个页面只调用依次
    onShow:function(){}, //监听页面显示
    onReady:function(){},//监听页面初次渲染完成,一个页面只调用1次
    onHidel:function(){},//监听页面隐藏
    onUnload:function(){} //监听页面卸载,一个页面只调用一次
})

WXS脚本

wxml中无法调用在页面的.js中定义的函数,但是 wxml中可以调用 wxs中定义的函数。因此,小程序中wxs的典型应用场景就是过滤器

wxs和JS的关系

  • 有自己的数据类型
  • number:数值类型、String 字符串类型、boolean:布尔类型、object:对象类型
  • function:函数类型、array:数组类型、data:日期类型、regexp:正则
  • wxs不支持类型ES6以上的语法形式
  • 不支持:let、const、解构赋值、展开运算、箭头函数、对象属性简写
  • 支持:var定义变量、普通function函数等类似与ES5的语法
  • wxs遵循CommonJS规范
  • module对象
  • require()函数
  • module.exports对象

基本语法

内嵌wxs脚本

可以编写在wxml文件中的 标签内,就行javascript代码可以编写在html文件中的