XP Fieldbook

微信小程序

image

项目结构

image

pages-目录

image

  • 所有的小程序页面存放处,每个页面以文件夹的形式存在

  • JSON文件:遵循就近原则

    {
      内容;
    }
  • WXML与HTML:

    标签不一样对应:HTML(div,span,img,a)WXML(view,text,image,navigator)。提供了VUE语法:数据绑定,列表渲染,条件渲染

  • WXSS与CSS

    WXSS增加了rpx尺寸单位(根据屏幕自动换算)。WXSS仅支持部分CSS样式(支持:.class类,#id,元素选择器,并集选择器,后代选择器,::after,::before伪类选择器)

  • JS:

    Page({ 用来创建并运行页面
      data: {页面的初始数据},
      onLoad(options) {生命周期函数--监听页面加载},
      onReady() {生命周期函数--监听页面初次渲染完成},
      onShow() {生命周期函数--监听页面显示},
      onHide() {生命周期函数--监听页面隐藏},
      onUnload() {生命周期函数--监听页面卸载},
      onPullDownRefresh() {页面相关事件处理函数--监听用户下拉动作},
      onReachBottom() {页面上拉触底事件的处理函数},
      onShareAppMessage() {用户点击右上角分享}
    })

app.js-启动

  • 小程序启动的入口-通过调用App函数创建小程序实例。
App({});

生命周期

  • 分为两类:应用生命周期(小程序从启动-运行-销毁的全过程)页面生命周期
  • 生命周期函数:代表的是某个时间点,生命周期强调的是某个时间段

应用生命周期函数

  • 再app.js中进行声明和调用,全局只会触发一次。
Page({ onLaunch() { 小程序初始化完成后会执行里面的代码 }, onShow(){
小程序启动,从后台转换到前台时触发 }, onHide(){ 小程序从后台转换到前台时触发 }
})

页面的生命周期函数

  • 需要再每个页面的JS文件夹内定义
Page({ onLoad(options) { 监听页面的加载,加载时触发,只调用一次,初始化数据 },
onReady() { 页面初次渲染完成触发,只调用一次 }, onShow() {
监听页面的显示,显示时触发 }, onHide() { 页面隐藏时触发 }, onUnload() {
页面销毁/卸载时触发,只触发一次 }, onPullDownRefresh() { 用户用户下拉动作时触发
}, onReachBottom() { 上拉触底事件 }, onShareAppMessage() { 用户点击右上角分享 }
})

app.json-配置

  • 全局配置文件,包含页面路径,窗口外观,页面表现,底部tab等
{
  "pages": [ pages配置小程序的页面路径,创建页面也在这里--创建页面
    "pages/index/index", 第一项为首页,需要调整可以移动
    "pages/logs/logs",
	"路径/页面文件夹/页面"
  ],
  "window": { window定义全局的页面背景和文字颜色(导航栏,背景区样式)
    "navigationBarTextStyle": "black",
    "navigationBarTitleText": "Weixin",
    "navigationBarBackgroundColor": "#ffffff" 窗口页面背景颜色
  },
  "style": "v2", 使用最新的样式,删除使用旧样式
  "componentFramework": "glass-easel",
  "sitemapLocation": "sitemap.json", 指明sitemap.json文件的位置
  "lazyCodeLoading": "requiredComponents"
}

window

  • 常用的配置项
属性名 类型 默认值 说明
navigationBarTitleText String 字符串 导航栏标题文字
navigationBarBackgroundColor HexColor #000000 导航栏的背景颜色(默认白色,仅支持16进制颜色)
navigationBarTextStyle String white 导航栏标题颜色(仅支持black/white)
backgroundColor HexColor #ffffff 窗口的背景颜色
backgroundTextStyle Striing dark 下拉刷新三个原点的颜色(仅支持dark/light)
enablePullDownRefresh Boolean false 是否开启全局下拉刷新(true false)
onReachBottomDistance Number 50 页面上拉触底事件的距离(单位px)上拉加载更多数据
{
  "window": {
    "navigationBarTitleText": "示例", 更改微信的顶头标题为示例
  },
}

tabBar-底部/顶部分栏

image

  • 分栏最少分配2个,最多分配5个,顶部的分栏不能显示图片

tabBar的组成部分:

image

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

tabBar配置项:

属性 类型 必填 默认 说明
list Array数组 是 标签列表
position String 否 botton 导航分栏的位置bottom底部top顶部
borderStyle String 否 black 上边框颜色(仅支持black/white)
color HexColor 否
未选中字体颜色
selectedColor HexColor 否 选中时文字的颜色
backgroundColor HexColor 否 背景颜色

list配置项:

属性 类型 必填 说明
pagePath String 是 导航对应-页面的路径
text String 是 导航显示的文字
iconPath String 否 未选中时图标路径(top不显示)
selectedlconPath String 否 选中时图标路径(top不显示)

示例:

image

{
  "pages": [
    "pages/index/index",  tabBar对应的页面需要放在前面
    "pages/test/test"
  ],
  "tabBar": {
      "list": [
          {
              "pagePath": "pages/index/index",  第一个配置项的页面必须放在前面
              "text": "首页"
          },
          {
              "pagePath": "pages/test/test",
              "text": "测试"
          }
      ],
      "position": "top"
  },
}

tabBar-自定义

  • 在 app.json​ 中的 tabBar​ 项指定 custom​ 字段,同时其余 tabBar 相关配置也补充完整。

  • 所有 tab 页的 json 里需声明 usingComponents​ 项,也可以在 app.json 全局开启。

    • 为了保证低版本兼容以及区分哪些页面是 tab 页,tabBar 的相关配置项需完整声明,但这些字段不会作用于自定义 tabBar 的渲染。
  • 默认在底部

{ "tabBar": { "custom": true, 自定义tabBar "color": "#000000", "selectedColor":
"#000000", "backgroundColor": "#000000", "list": [{ "pagePath":
"page/component/index", "text": "组件" }, { "pagePath": "page/API/index",
"text": "接口" }] }, "usingComponents": {} }

添加tabBar页面:

custom-tab-bar/index.js custom-tab-bar/index.json custom-tab-bar/index.wxml
custom-tab-bar/index.wxss

在index.json导入组件

{ "component": true, "usingComponents": { "van-tabbar": "vant-weapp/tabbar",
"van-tabbar-item": "vant-weapp/tabbar-item" } }

基础使用:

可选参数:

参数 说明 类型 默认值
active 当前选中标签的索引 number -
fixed 是否固定在底部 boolean true
placeholder 固定在底部时,是否在标签位置生成一个等高的占位元素 boolean false
border 是否展示外边框 boolean true
z-index 元素 z-index number 1
active-color 选中标签的颜色 string #1989fa
inactive-color 未选中标签的颜色 string #7d7e80
safe-area-inset-bottom 是否为 iPhoneX 留出底部安全距离 boolean true
<van-tabbar active="{{ active }}" bind:change="onChange">
  <van-tabbar-item icon="home-o">标签</van-tabbar-item>
  <van-tabbar-item icon="search">标签</van-tabbar-item>
  <van-tabbar-item icon="friends-o">标签</van-tabbar-item>
  <van-tabbar-item icon="setting-o">标签</van-tabbar-item>
</van-tabbar>

// custom-tab-bar/index.js Component({ data: { active: 0, }, methods: {
onChange(event) { // event.detail 的值为当前选中项的索引 this.setData({ active:
event.detail }); }, } })

自定义标签

  • slot="icon"​表示选未中,slot="icon-active"​表示选中,info="3"表示徽标(未读消息的数字)
<!--custom-tab-bar/index.wxml-->
<van-tabbar active="{{ active }}" bind:change="onChange">
  <van-tabbar-item info="3">
    <image
      slot="icon"
      src="{{ icon.normal }}"
      mode="aspectFit"
      style="width: 30px; height: 18px;"
    />
    <image
      slot="icon-active"
      src="{{ icon.active }}"
      mode="aspectFit"
      style="width: 30px; height: 18px;"
    />
    标签位置
  </van-tabbar-item>
</van-tabbar>

怎么在点击时切换页面

  • 在基础使用中定义了一个方法用来获取当前的索引值
  • 可以使用API:wx.switchTap({})来切换页面(可以参考组件-页面跳转-导航)
methods: { onChange(event) { // event.detail 的值为当前选中项的索引
this.setData({ active: event.detail }); }, }

‍

页面和全局JSON

  • 遵循就近原则,大部分规则与全局一致
  • 默认是设置导航栏和背景区,不用使用window包裹

示例-更改顶栏颜色:

JSON
{
  "usingComponents": {},
  "navigationBarBackgroundColor": "#ffffff"
}

页面的配置项就是全局中的:window部分

属性名 类型 默认值 说明
navigationBarTitleText String 字符串 导航栏标题文字
navigationBarBackgroundColor HexColor #000000 导航栏的背景颜色(默认白色,仅支持16进制颜色)
navigationBarTextStyle String white 导航栏标题颜色(仅支持black/white)
backgroundColor HexColor #ffffff 窗口的背景颜色
backgroundTextStyle Striing dark 下拉刷新三个原点的颜色(仅支持dark/light)
enablePullDownRefresh Boolean false 是否开启当前页面下拉刷新(true false)
onReachBottomDistance Number 50 页面上拉触底事件的距离(单位px)上拉加载更多数据

project.config.json

{
  "compileType": "miniprogram", 说明
  "libVersion": "trial",
  "packOptions": {
    "ignore": [],
    "include": []
  },
  "setting": { 开发者工具的个性化配置(就是详情-本地设置)
    "coverView": true,
    "es6": true,
    "postcss": true,
    "minified": true,
    "enhance": true,
    "showShadowRootInWxmlPanel": true,
    "packNpmRelationList": [],
    "babelSetting": {
      "ignore": [],
      "disablePlugins": [],
      "outputPath": ""
    }
  },
  "condition": {},
  "editorSetting": {
    "tabIndent": "auto",
    "tabSize": 2
  },
  "appid": "wxe66711a6c4eae073" 微信APPID
}

sitemap.json-索引

  • 小程序内搜索,但用户搜索词与小程序内匹配时将小程序优先显示
{
  "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
  "rules": [{
  "action": "allow", allow允许全部页面索引,disallow不索引
  "page": "*"
  }]
}

WXS脚本

  • 就是再HTML页面写JS代码,然后调用(在微信中一般将WXS脚本作为过滤器使用,过滤数据)
  • 使用WXS​标签定义,使用module​属性来定义函数的名字,使用module.exports.名字​来导出函数/变量的名字,再HTML中使用

示例:

<view>{{test.Num(1)}} {{test.name}}</view>
<wxs module="test">
  module.exports.Num = function(num){ return num } module.exports.name = "xinp"
</wxs>

引入外部WXS文件

  • 以wxs为结尾的文件都可以引入
  • 使用WXS​标签中的src​属性进行导入(路径只能使用相对路径),再WXS文件中使用function​定义函数名,使用module.exports​导出内部的函数名再{外部使用名:内部名称}导出

示例:

<!--test.wxml-->
<text>这里是测试taBer</text>
<view>{{test.Num(1)}}</view>
<wxs module="test" src="test.wxs"></wxs>

// test.wxs function toNum(num){ return num; } module.exports = { Num:toNum }

只能和​ ​{{}}​​使用,并与微信环境相互隔离不能使用小程序的API

格式化手机号-示例

<!--test.wxml-->
<text>这里是测试taBer</text>
<view>{{tool.spList("18153422415")}}</view>
<wxs module="tool" src="test.wxs"></wxs>

// test.wxs function spList(srt){ if( srt.length !== 11){
判断传入的是否为11为手机号 return srt; } var arr = srt.split('')
将字符串分解成数组 arr.splice(3,0,'-')
splice(位置,删除几个,插入什么)用于再数组中添加字符 arr.splice(8,0,'-')
return arr.join('') 将数组重新拼接为字符串 } module.exports = { spList:spList }

组件

视图-组件

  • 作用与WXML,用于定义页面结构

view-框架

  • 类似于html的div,普通视图区域,用于划分区域

示例:

image

<!--test.wxml-->
<view class="container">
    <view>A</view>
    <view>B</view>
</view>
/* test.wxss */
.container view{ 选择container类下的所有view
    width: 100px;
    height: 100px;
    text-align: center;
    line-height: 100px;
}
.container view:nth-child(1){ 选择container类下的第一个view
    background-color: lightgreen;
}
.container view:nth-child(2){
    background-color: lightskyblue;
}
.container { 设置container类view
    display: flex; 横向
    justify-content: space-around; 阔排列
    flex-direction: row; 强制横向
}

scroll-view-滚动列表

  • 可滚动的视图区域,常用作滚动列表效果

示例:

<!-- 在 WXML 文件中 -->
<scroll-view
  scroll-y            <!-- 启用纵向滚动 -->
  scroll-top="100"    <!-- 初始滚动位置(垂直方向) -->
  show-scrollbar=""      <!-- 显示滚动条 -->
  style="height: 300px;"
>
  <!-- 这里放置需要滚动的内容 -->
  <view class="content">内容1</view>
  <view class="content">内容2</view>
  <!-- ...更多内容 -->
</scroll-view>

属性:

属性名 作用 类型 默认
scroll-x 是否允许横向滚动 Boolean false
scroll-y 是否允许纵向滚动 Boolean false
scroll-top 滚动条的垂直位置(单位px) Number 0
scroll-left 滚动条的水平位置(单位px) Number 0
scroll-into-view 滚动到指定id的子元素 String -
enable-back-to-top 是否开启回弹到顶部功能 Boolean true
show-scrollbar 是否显示滚动条 Boolean true
scroll-with-animation 滚动是否带有动画效果 Boolean false
upper-threshold 滚动到顶部边界触发事件的阈值(单位px) Number 50
lower-threshold 滚动到底部边界触发事件的阈值(单位px) Number 50

示例:

<!-- WXML -->
<scroll-view
  scroll-y
  scroll-into-view="{{targetId}}"
  当
  targetId
  的值与某个子元素的
  id
  属性匹配时,scroll-view
  会自动滚动到该元素的位置。
  bindscrolltoupper="onScrollToUpper"
  当滚动到顶部
  时触发的事件处理函数
  onScrollToUpper
  bindscrolltolower="onScrollToLower"
  当滚动到底部
  时触发的事件处理函数
  onScrollToLower
  style="height: 500px;"
>
  <view
    wx:for="{{list}}"
    wx:key="index"
    class="item"
    style="height: 100px;"
    data-id="item{{index}}"
  >
    {{item}}
  </view>
</scroll-view>
// JS
Page({
  data: {
    list: Array.from({ length: 20 }, (_, i) => `Item ${i + 1}`),
    targetId: "", // 用于跳转到指定ID的元素
  },
  // 滚动到顶部触发
  onScrollToUpper() {
    console.log("滚动到顶部");
    // 可以触发加载更多数据
  },
  // 滚动到底部触发
  onScrollToLower() {
    console.log("滚动到底部");
    // 可以触发加载更多数据
  },
  // 跳转到指定项(例如点击按钮触发)
  scrollToItem(e) {
    const id = e.currentTarget.dataset.id;
    this.setData({ targetId: id });
  },
});

swiper-轮播图

image

  • swiper swiper-item 轮播图容器
<swiper indicator-dots>
  显示轮播图下的点
  <swiper-item>
    <view>A</view>
  </swiper-item>
  <swiper-item>
    <view>B</view>
  </swiper-item>
</swiper>

swiper { height: 150px; 定义轮播图容器的高 } swiper swiper-item view{ height:
100%; list-style: 150px; text-align: center; 文字居中 } swiper
swiper-item:nth-child(1) view{ background-color: lightpink; 设置A的颜色 } swiper
swiper-item:nth-child(2) view{ background-color: lightseagreen; 设置B的颜色 }

属性

属性名 作用 类型 默认值
indicator-dots 是否显示面板指示点 Boolean false
indicator-color=“” 指示点的颜色 color rgba(0, 0, 0, .3)
indicator-active-color=“” 当前选中的颜色 color #00000000
autoplay 是否自动切换默认5s Boolean false
interval
自动切换的时间 number 5000
circular
是否循环播放 Boolean false

WXML-内容组件

  • 用于填充内容

text-文本

  • 类似于html的span标签,是一个行内元素
<view>
  <text>文本</text>
</view>

属性

属性 作用 默认 值
selectable="" 是否支持长按复制 false Boolean

input-输入

  • 输入的文本框

基础写法:<input type="类型" name="" id=""/>

<input
  type="输入类型"
  placeholder="请输入内容"
  value="{{将文本框的数据与JSdata中的数据进行绑定}}"
  bindinput="监听输入事件"
  bindblur="监听失去焦点事件"
/>

属性:

属性名 作用 类型 默认
value 输入框的当前值(需绑定到 data),就是默认显示 String/Number ''
type 输入类型(如文本、数字、密码等) String text
placeholder 输入框为空时的占位符文字 String -
disabled 是否禁用输入框 Boolean false
maxlength 最大输入长度(超出后无法输入) Number 1000
focus 是否自动聚焦(获取焦点) Boolean false
password 是否显示密码模式(显示为圆点) Boolean false
cursor-spacing 光标与输入框右侧的最小距离(单位px) Number 0
confirm-type 设置键盘右下角按钮的文本(如“搜索”、“发送”等) String done
confirm-hold 点击键盘右下角按钮时是否保持键盘不收起 Boolean false

Type的值:

值 说明
text 普通文本输入(默认)
number 数字键盘输入
idcard 身份证号输入(软键盘包含 X/x 字母)
digit 数字和小数点输入(如价格)
textarea 多行文本输入(需配合style设置高度)

常用的事件监听: 使用方法可参考事件绑定部分

事件名 触发条件 事件参数
bindinput 输入时触发(实时更新) value:当前输入的值
bindblur 失去焦点时触发 value:当前输入的值
bindfocus 获得焦点时触发 value:当前输入的值
bindconfirm 点击键盘右下角按钮时触发 value:当前输入的值

rich-text-富文本

image

  • 将html字符串渲染为wxml结构
<rich-text nodes="html内容" />

示例:
<rich-text nodes="<h1 style='color:red'>标题</h1>" />

button-按钮

  • 通过open-type属性可以调用微信提供的各种功能(客服、转发、获取用户授权、获取用户信息等)

image

<view>
  <button>默认</button>
  <button type="primary">背景主色调</button>
  <button type="default">文字主色调</button>
  <button type="warn">警告</button>

  可以组合使用
  <button type="primary" size="mini">迷你</button>
  <button plain="true">镂空</button>
</view>

image-图片

  • 有默认的宽高

image

<view>
  <image src="路径" mode="值" /> 微信的默认路径为/ 如pages就是:/pages
</view>

mode属性

值 说明
scaleToFill 默认 将图片完整填充元素
aspectFit 缩放 将图片的长边完整的显示出来
aspectEill 缩放 将图片的短边完整的显示出来
widthFix 缩放 元素自适应高度-宽度不变
heightFix 缩放 元素自适应宽度-高度不变

form-表单

  • 填写表单并进行提交
  • <form bindsubmit="处理提交的方法">​,使用button​的form-type="submit"​属性触发自定义提交函数,form-type="reset"属性重置输入的内容
<form bindsubmit="setData">
  <input name="name" placeholder="输入名字"></input>
  <button type="primary" form-type="submit">
    提交
  </button>
  <button form-type="reset">重置</button>
</form>;

// pages/index/index.js
Page({
  setData(e) {
    console.log(e.detail.value.name);
  },
});

解构方法

  • var { 对象中的数据名称 } = 对象名称,将对象中的对象名称对应提取出来
Page({
  setData(e) {
    var { name } = e.detail.value;
    console.log(name);
  },
});

WXJS-语法

{{}}-数据绑定

  • 将JS中的数据绑定在WXML中

示例:

<!--wxml-->
<view>{{name}}</view>

//JS JS中声明变量的方式 变量名:"值", Page({ data: { name:"xinp", }, })

{{}} 语法:

  • 动态绑定变量(与VUE一致):<标签> {{变量名}} </标签> 会自动绑定JS中data的变量
  • 动态绑定属性:<标签 属性="{{变量名}}"></标签> 会自动将JS中data变量写入
  • 三元运算:<标签> {{表达式 ?'ture值':'flas值'}} </标签> 表达式可以使用JS的变量
  • 算数运算:<标签> {{ 10 * 10 }} </标签>

事件绑定

  • 用户行为触发器

image

常用的事件:下列会依次介绍

  • 点击:bindtap 或 bind:tap 类似与HTML的click事件
  • 文本框事件:bindinput 或 bind:input 文本框输入
  • 状态改变:bindchange 或 bind:change 状态改变时触发

event-事件对象的属性

  • 当事件被触发时会受到一个对象event,详细属性如下:
属性 类型 说明
target Object 触发事件的组件的一些属性的集合
detail Object 额外的信息
type string 事件类型
timeStamp Integer 页面打开到触发事件所经过的毫秒数
currentTarget Object 当前组件的一些属性值集合
touches Array 触摸事件,当前停留在屏幕中的触摸点信息的数组
changedTouches Array 触摸事件,当前变化的触摸点信息的数组

​bind:tap​​ 点击 示例:bind:tap="点击触发的函数方法"

<!--wxml-->
<button type="primary" bind:tap="onTap">点击</button>

//JS Page({ data: {}, onTap(e) { 这里的e代表event,可以进行简写 console.log(e);
打印日志 }, })

更改data数据

  • 在JS的自定义函数/方法中给改定义的data数据
  • 自定义函数/方法获取data的值:通过this.data.变量名的方式

​this.setData(dadaObject)​ :

  • this.setData({变量名:新值})
<!--wxml-->
<button type="primary" bind:tap="onAdd">点击+1</button>
<text>{{count}}</text>

//JS Page({ data: { count:1 定义的变量 }, onAdd(){ this.setData({ 取得data内的值
count:this.data.count+1 自增 }) } })

事件传参

  • 在VUE中可与在定于函数的同时可与传参(<button bindtap="onAdd(1)">点击</button>​),WXML不行(会将onAdd(1)当成函数的名字)
  • 传参:​data-*="{{值}}"​ ​这里的*代表的时传入参数的名字( ​{{值}}​ 部分如果直接写传入的是文本,传入数字需要{{}})
  • 接收参数:​event.target.dataset.参数名字​

示例:

<!--wxml-->
<button type="primary" bind:tap="onAdd" data-info="{{2}}">点击+1</button>
<text>{{const}}</text>

//JS Page({ data: { const:1 }, onAdd(event){ this.setData({
const:event.target.dataset.info+1 }) }

事件冒泡:target与currentTarget区别

当button被触发时,view也将被触发(包括绑定的方法等)

<view>
  <button>按钮</button>
</view>
  • target:触发该事件的源头事件
  • currentTarget:当前事件绑定的组件
  • 对于外层view来说:e.target​指的是谁触发的事件这里是button,e.currentTarget指的是当前正在触发的事件这里指的是view

​bindinput 或 bind:input​ 文本框 示例:

  • 怎么实时获得文本框的内容:e.detail.value(文本框的内容会实时写入JS的data内)
<!--wxml-->
<input type="text" bindinput="inputHan" name="" id="" />
<text>{{txt}}</text>

//JS Page({ data: { txt:"" }, inputHan(e){ this.setData({ txt:e.detail.value })
} })

wx:if-条件渲染

  • 根据判断条件来判断某个元素是否渲染

写法:wx:if="判断语句" 如果 wx:elif="判断语句" 否则 wx:else 另外

<!--wxml-->
<view wx:if="{{conus === 1}}">当前为1</view>
<view wx:elif="{{conus === 2}}">当前为2</view>
<view wx:else="">其他</view>

//JS Page({ data: { conus:0, }, })

怎么一次性显示/隐藏多个组件:

  • 就是使用一个组件将其余内容包裹起来(如view)
  • 使用组件:<block> 内容 </block> 这个组件没有任何作用,就是简单的起到包裹作用,与HTML的template一致
<block wx:if="{{ture}}">
  <view>A</view>
  <view>B</view>
</block>

属性-hidden-隐藏

  • hidden="{{值}}"的默认是隐藏,这个属性的对于大部分组件都有效果
  • 与wx:if的否定一样可以进行隐藏元素,hidden是切换元素的样式来隐藏,wx:if是动态创建和移除元素

示例:

<view hidden="{{ture}}}"> 默认隐藏 </view>

wx:for-列表渲染

  • 用于将数组内的相同结构的数据

简单写法:<标签 wx:for="{{要遍历的东西}}">{{item 默认当前值}} {{index 默认索引}}</标签>

<!--wxml-->
<view wx:for="{{name}}">当前编号:{{index}} 当前值:{{item}}</view>

//JS Page({ data: { name:["xinp","xinzhu"], }, })

手动指定索引名与当前变量名:

  • wx:for-index="索引名":来指定当前索引名
  • wx:for-item="当前变量名":来指定当前的变量名
<!--wxml-->
<view wx:for="{{name}}" wx:for-index="newindex" wx:for-item="newitem"
  >当前编号:{{newindex}} 当前值:{{newitem}}</view
>

//JS Page({ data: { name:["xinp","xinzh"], }, })

​wx:key=""​ ​列表绑定:

  • 在进行for渲染时,推荐使用key将列表进行绑定,绑定时将循环中不重复的项进行唯一绑定
  • 没有唯一ID,可以使用索引(index)
<!--wxml-->
这里填id,遍历列表得到的是{id:1,name:"xinp"},填id会自动将解析的id作为唯一值进行绑定
<view wx:for="{{name}}" wx:key="id"
  >当前编号:{{index}} 当前值:{{item.name}}</view
>

//JS Page({ data: { name:[ 访问数组内的某个特定项内容可以使用(.)的方式
{id:1,name:"xinp"}, {id:2,name:"xinzhu"} ] }, })

生成随机数

  • 使用方法:​Math.random()​ 会随机生成一个[0,1)之间的随机数
  • 生成指定范围之间的随机数:Math.random() * (max - min) + min
  • 生成指定范围之间的整数:Math.floor(Math.random() * (max - min + 1)) + min

示例: 在正常页面使用方法一致

<!--components/test/test.wxml-->
<view>这里是组件</view>
<button bind:tap="onRan">生成随机数{{const}}</button>

// components/test/test.js Component({ methods: { onRan(){ this.setData({
const:Math.floor(Math.random()*100) 生成0到100之间的整数 }) } }, })

‍

WXSS

  • 负责页面的美化部分
  • 大部分用法与HTML的CSS一致,独有的特性有rpx(自适应尺寸每个屏幕都分成750份)@import(样式引入)

样式导入​@import "css相对路径"

/* WXSS */ @import "/pages/app.wxss"

全局CSS变量

  • 使用自定义变量名称存储CSS样式,方便统一管理

在正常HTML内的写法:

写在CSS部分,在html内顶级节点为html/root,因为定义的自定义变量是由作用域的
选择节点{ --变量名称:值 } 选择{ 属性值:var(--变量名称) } /*
pages/temp/temp.css */ :root { --coler:red; } .Ctext { color: var(--coler); }

在微信小程序中进行使用:

  • 微信的顶级节点为:Page

  • 在全局样式声明Page节点:写入自定义样式

    /**app.wxss**/ page{ --colorRed:red; }
  • 在任意页面的WXSS进行应用

    <!--pages/temp/temp.wxml-->
    <text class="Ctext">这里是首页</text>
    
    /* pages/temp/temp.wxss */ .Ctext { color: var(--colorRed); }

‍

自定义组件

  • 封装可复用的 UI 组件和业务逻辑,与VUE的插槽概念类似

创建组件目录:

  • 新建文件夹components,将自定义的组件存放在components内
  • 再components内新建一个组件名文件夹
  • 点击创建imagecomponent

挂载组件

  • 局部挂载(只能再挂载的页面使用):

    • 再页面的JSON内写入需要挂载的组件

      { "usingComponents": { "自定义引用组件的名称":"绝对路径" } } {
      "usingComponents": { "my-v":"/pages/components/test/test" } }
    • 使用:自定义组件的名称将会作为自定义组件使用<my-v></my-v>

  • 全局挂载:再app.json中声明一个usingComponents​(写法与局部引用一致)它与pages,window同级,在每个页面就可以进行使用了

示例:

<!--components/test/test.wxml-->
<view>这里是组件</view>

<!--pages/temp/temp.json-->
{ "usingComponents": { "my-v":"/components/test/test" } }
<!--pages/temp/temp.wxml-->
<text>这里是首页</text>
<my-v></my-v>

组件页面与普通页面的区别

  • 页面结构大体类似

  • 在组件的JSON文件中需要声明:"component": true

    { "component": true, "usingComponents": {} }
  • 在组件的JS文件中调用的是Component​函数,普通页面调用的是Page函数

    组件:Component({}) 普通:Page({})
  • 组件的自定义函数只能写在:methods​中,普通页面与data,onLoad等平级

    组件: Component({ methods: { 写自定义方法的地方 } }) 普通页面: Page({ data:
    {}, 自定义函数 onLoad(options) {}, })

组件的样式隔离

  • 组件中的样式文件只对组件起作用,全局定义的样式对组件不起作用(只有class类选择器不起作用,id选择器,属性选择器,标签选择器不受影响)

  • 怎么修改组件的样式隔离:

    • 方式1:在组件的JS文件中添加配置

      Component({ options:{ styleIsolation:"isolated" }, })
    • 方式2:在组件的JSON文件中添加配置

      { "component": true, "styleIsolation": "isolated", 新添加的配置
      "usingComponents": {} }
  • ​styleIsolation​的可选值:

    • isolated 默认值,启用样式隔离
    • apply-shared普通页面的样式可以影响的组件的样式
    • shared 双向影响,页面和组件定义的样式相互影响

methods-自定义函数

  • 组件中的自定义函数只能在methods中写
  • 一般自定义方法使用_下划线开头,页面事件处理函数正常写

示例:

<!--components/test/test.wxml-->
<view>这里是组件</view>
<button bind:tap="onBat">const当前的值{{const}}</button>

// components/test/test.js Component({ data: { const:0 }, methods: { onBat(){
this.setData({ const:this.data.const+1 }) this._showOnBat() }, _showOnBat(){
wx.showToast({ title: '+1', }) } } })

properties-接收数据

  • 接收来自自定义标签的参数,与VUE自定义标签一致

  • 需要接收的参数需要定义在:properties内

    • 简写:外部名称:数据类型
    • 完整:外部名称:{ type:数据类型,value:默认值}
  • 在组件HTML内使用和在data内定义的变量一致,在自定义函数中使用需要指定this.properties.外部名称

  • 微信小程序中的properties与data是一致的,可读可写,只是人外区分内部变量与外部变量

示例:

<!--components/test/test.wxml-->
<view>这里是组件</view>
<button bind:tap="onTap">{{name}}当前值:{{const}}</button>

// components/test/test.js Component({ properties: { max:Number, name:{
type:String, value:"xinp" } }, data: { const:0 }, methods: { onTap(){
if(this.data.const >= this.properties.max){ wx.showToast({ title:
'已经超过当前最大值', }) return } this.setData({ const:this.data.const+1 }) } }
})

<!--pages/temp/temp.wxml-->
<text>这里是首页</text>
<my-v max="5" name="xinzhu"></my-v>
<!--pages/temp/temp.json-->
{ "usingComponents": { "my-v":"/components/test/test" } }

怎么修改properties中的值:与修改data的方法一致,只不过前缀改为​​this.properties.变量​

<!--components/test/test.wxml-->
<view>这里是组件</view>
<button bind:tap="onTap">{{name}}当前值:{{const}}</button>
<view>{{max}}</view>

// components/test/test.js Component({ properties: { max:Number, name:{
type:String, value:"xinp" } }, data: { const:0 }, methods: { onTap(){
if(this.data.const >= this.properties.max){ wx.showToast({ title:
'已经超过当前最大值', }) return } this.setData({ const:this.data.const+1,
max:this.properties.max+1 }) } } })

observers-数据监听

  • 在监控的数据变动时执行某些方法(如自动计算价格等)
  • 需要在JS文件中的observers节点中定义
    • 格式: ​'值1,值2,...':function(值1,值2,...){代码块}​
    • 在前面监控的值发生变动时触发​function​​定义的函数,前后参数一一对应,​function​的参数名可以自由更改,值会一一对应。

示例:监听值的变化 在两个数字变动后和也将变动

<!--components/test/test.wxml-->
<view>这里是组件</view>
<view>num1:{{num1}} num2:{{num2}} 和:{{sum}}</view>
<button bind:tap="onNum1">num1值加一</button>
<button bind:tap="onNum2">num2值加一</button>

// components/test/test.js Component({ data: { num1:0, num2:0, sum:0 }, methods:
{ 两个数字的自增 onNum1(){ this.setData({ num1:this.data.num1+1 }) }, onNum2(){
this.setData({ num2:this.data.num2+1 }) } }, observers:{
在数字自增后和将会自动变化 'num1,num2':function(num1,newnum2){ this.setData({
sum:num1+newnum2 }) } } })

监控对象:对象名.变量即可 这是调用对象内的值的通用语法

  • 使用单引号''​或则双引号""引起来
<!--components/test/test.wxml-->
<view>这里是组件</view>
<view>num1:{{num.num1}} num2:{{num.num2}} 和:{{num.sum}}</view>
<button bind:tap="onNum1">num1值加一</button>
<button bind:tap="onNum2">num2值加一</button>

// components/test/test.js Component({ data: { num:{ num1:0, num2:0, sum:0 } },
methods: { onNum1(){ this.setData({ 'num.num1':this.data.num.num1 + 1 }) },
onNum2(){ this.setData({ 'num.num2':this.data.num.num2 + 2 }) } }, observers:{
'num.num1,num.num2':function(num1,num2){ this.setData({ 'num.sum':num1+num2 }) }
} })

监控所有变动:

  • 可以使用通配符**来指定所有对象
  • 接收到的是一个对象
  • 注意如果监听的对象和修改的对象为同一个将会引发无限循环

示例: 这个例子中的sum不能再num对象内

<!--components/test/test.wxml-->
<view>这里是组件</view>
<view>num1:{{num.num1}} num2:{{num.num2}} 和:{{sum}}</view>
<button bind:tap="onNum1">num1值加一</button>
<button bind:tap="onNum2">num2值加一</button>

// components/test/test.js Component({ data: { num:{ num1:0, num2:0 }, sum:0 },
methods: { onNum1(){ this.setData({ 'num.num1':this.data.num.num1 + 1 }) },
onNum2(){ this.setData({ "num.num2":this.data.num.num2 + 2 }) } }, observers:{
'num.**':function(obj){ this.setData({ sum:obj.num1+obj.num2 }) } } })

纯数据字段

  • 定义的data中的变量不用于向外传递数据,页面{{}}引用,用于定义这个页面的给某个状态量等就可以使用纯数据段
  • 使用纯数据可以提高页面性能
  • 如何定义:
    • 在Component​内定义options​,并添加pureDataPattern:正则表达式
    • 会在data中寻找满足正则表达式的变量,将不被渲染在页面上

示例:

<!--components/test/test.wxml-->
<view>这里是组件</view>
<view>{{name}} {{_age}}</view> 这里的_age无法渲染 // components/test/test.js
Component({ options:{ pureDataPattern:/^_/ } data: { name:"xinp", _age:20 }, })

组件的生命周期

生命周期函数 参数 描述说明
created 无 在组件实例刚刚被创建时执行,不能调用setData
attached 无 在组件实例进入页面节点树时执行,用于数据初始化
ready 无 在组件在视图层布局完成后执行
moved 无 在组件实例被移动到节点树另一个位置时执行
detached 无 在组件实例被从页面节点树移除时执行
error Object Error 每当组件方法抛出错误时执行

怎么进行声明

  • 新方法(推荐):在lifetimes(与data平级)节点中进行声明
  • 直接与data平级声明
  • 新旧同时声明会将以新的为准

示例:

// components/test/test.js Component({ lifetimes:{ created(){}, attached(){} },
})

组件所在页面的生命周期

  • 组件需要挂载在正常的页面才能展示,如果希望在挂载的页面某个生命周期时执行组件的某些方法就需要组件所在的生命周期
生命周期函数 参数 描述
show 无 组件所在的页面被展示时执行
hide 无 组件所在的页面被隐藏时执行
resize Object Size 组件所在的页面尺寸变化时执行

如何在组件内进行声明

  • 需要在pageLifetimes(与data平级)节点中进行声明

示例:

// components/test/test.js Component({ pageLifetimes:{ show:function(){},
hide(){} resize:function(size){} }, })

slot-自定义组件插槽

  • 在组件需要使用者的内容变化来变化时,可以使用slot标签,定义插槽(与VUE插槽概念一致)
  • 默认每个组件只能使用一个插槽

示例:

<!--components/test/test.wxml-->
<view>这里是组件</view>
<slot></slot>

<!--pages/temp/temp.wxml-->
<text>这里是首页</text>
<my-v>
  <view>这是插入组件的内容</view>
</my-v>

怎么使用多个插槽

  • 在options​(与data平级)中声明multipleSlots:true启用多插槽
  • 定义多个插槽可以使用slot​的name属性,使用时添加属性slot=“name中定义的属性名”,在有多个插槽没有指定名字时,将不会显示

示例:

<!--components/test/test.wxml-->
<slot name="slot1"></slot>
<view>这里是组件</view>
<slot name="slot2"></slot>

// components/test/test.js Component({ options:{ multipleSlots:true }, })

<!--pages/temp/temp.wxml-->
<text>这里是首页</text>
<my-v>
  <view slot="slot1">这是插入组件的内容slot1</view>
  <view slot="slot2">这是插入组件的内容slot2</view>
</my-v>

组件间的通信

  • 属性绑定:父组件向子组件传递数据,仅支持JSON格式

    • 在组件的properties节点中声明存入的变量

    • 使用时,使用标签的属性变量名="值"的形式传递数据

    • <!--components/test/test.wxml-->
      <view>这里是组件</view>
      <view>这是父组件传递的数字:{{myconst}}</view>
      
      // components/test/test.js Component({ properties: { myconst:Number }, })
      
      <!--pages/temp/temp.wxml-->
      <text>这里是首页</text>
      <my-v myconst="{{const}}"></my-v>
      
      // pages/temp/temp.js Page({ data:{ const:5 }, })
      <!--pages/temp/temp.JSON-->
      { "usingComponents": { "my-v":"/components/test/test" } }
  • 事件绑定:子组件向父组件传递数据,任意数据

    • 在父组件定义一个函数,用于给子组件调用,在子组件调用时添加参数即可实现数据传递;父组件默认接收一个参数e(可参考WXJS语法-事件绑定部分的内容)

    • 在调用组件时使用:自定义组件的bind:组件内部使用的函数名="父组件函数名"属性,间父组件的函数传递给子组件

    • 在子组件内使用:this.triggerEvent("组件内部使用的函数名",{自定义e.detail中的数据名称:等于那个值})

    • 在父组件中通过:e.detail.自定义名称变量来接收数据

    • <!--components/test/test.wxml-->
      <view>这里是组件</view>
      <button bind:tap="addConst">增加子组件的数字</button>
      <view>这是父组件传递的数字:{{myconst}}</view>
      <button bind:tap="onConst">同步父子数据</button>
      
      // components/test/test.js Component({ properties: {
      属性绑定接收父组件的数据 myconst:Number }, methods: { addConst(){
      子组件的数字自增 this.setData({ myconst:this.properties.myconst+1 }) },
      onConst(){
      同步父子组件的数据,这里使用的时父组件传递的函数sync,定义e.detail.内的value(自定义名称)中
      this.triggerEvent("sync",{value:this.properties.myconst}) } }, })
      
      <!--pages/temp/temp.wxml-->
      <text>这里是首页</text>
      <my-v myconst="{{const}}" bind:sync="sanyConst"></my-v>
      <view>这是父组件的数字:{{const}}</view>
      
      // pages/temp/temp.js Page({ data:{ const:5 }, sanyConst(e){ this.setData({
      const:e.detail.value }) } }) // pages/temp/temp.JSON "usingComponents": {
      "my-v":"/components/test/test" } }
  • 获取组件实例:通过this.selectComponent()获取子组件的实例,父组件可以访问子组件的任意数据与方法

    • 这个方法会返回子实例的所有方法,数据

    • this.selectComponent()​:内只能支持类选择器,和id选择器(类用.​ ID用 #)

    • 调用组件内的方法时需要使用自定义时的变量,不能使用this(this表明的时当前)

    • <!--components/test/test.wxml-->
      <view>这里是组件</view>
      <view>这里是子组件的数字:{{myconst}}</view>
      
      // components/test/test.js Component({ properties: { myconst:Number },
      methods: { onAdd(){ this.setData({ myconst:this.properties.myconst+1 }) } },
      })
      
      <!--pages/temp/temp.wxml-->
      <text>这里是首页</text>
      <my-v myconst="{{const}}" id="cV" class="cvstm"></my-v>
      <button bind:tap="onChild">点击增加子组件的数字</button>
      
      // pages/temp/temp.js Page({ data:{ const:5 }, onChild(){ const child =
      this.selectComponent('.cvstm') console.log(child); child.setData({
      myconst:child.properties.myconst+1 }) child.onAdd() } })

behaviors-共享

  • 是用于组件之间代码共享的特性,包含数组,属性,生命周期,方法,。在组件使用共享时会合并到组件中
  • 组件可以使用多个behaviors,组件之间可以相互调用behaviors
  • 就是公共JS,建议将代码存放在公共目录

声明:module.exports="导出的名称"

module.exports=Behavior({ data:{ name:"xinp" }, properties:{}, methods:{} })

导入

  • 使用const 变量名 = require(相对路径)导入(与Component平级)
  • 在启动函数(Component)内声明:behaviors:[刚才声明的变量名,],因为共享是直接将代码引入本JS,所以按本JS声明的方法/数据使用即可
  • 只能在组件内使用
<!--components/test/test.wxml-->
<view>这里是组件</view>
<view>公共代码的名字:{{name}}</view>

// components/test/test.js const my_js = require('../../behaviors/my-js')
Component({ behaviors:[my_js], })

behaviors中可用的节点

可用的节点 类型 是否必填 描述
properties Object Map 否 同组件的属性
data Object 否 同组件的数据
methods Object 否 方法
behaviors String Array 否 引入其它的 behavior
created Function 否 生命周期函数
attached Function 否 生命周期函数
ready Function 否 生命周期函数
moved Function 否 生命周期函数
detached Function 否 生命周期函数

同名字段的覆盖和组合规则

  • 冲突遵循就近原则,不冲突为补充

  • 返回的是一个Pormise对象:并不是原版的对象,需要进行解构(从对象内拿东西)

async 自定义方法(){ const {Pormise对象内的: 新名字} = await wx.p.request({ url:
'url', }) } {:}:的作用是重命名,将前一个名字从定义为后一个名字,({data: res}
将data重命名为res) await :的作用是解构,将Pormise中的数据拿出来 示例: async
getInfo(){ const {data: res} = await wx.p.request({ url: 'url', })
console.log(res); 这将打印返回的Pormise对象的data数据 }
  • 如果有同名的属性 (properties) 或方法 (methods) :

    1. 若组件本身有这个属性或方法,则组件的属性或方法会覆盖 behavior 中的同名属性或方法;
    2. 若组件本身无这个属性或方法,则在组件的 behaviors​ 字段中定义靠后的 behavior 的属性或方法会覆盖靠前的同名属性或方法;
    3. 在 2 的基础上,若存在嵌套引用 behavior​ 的情况,则规则为:父 behavior​ 覆盖子 behavior 中的同名属性或方法。
  • 如果有同名的数据字段 (data) :

    • 若同名的数据字段都是对象类型,会进行对象合并;
    • 其余情况会进行数据覆盖,覆盖规则为:组件 > 父 behavior​ > 子 behavior​、靠后的 behavior​ > 靠前的 behavior。(优先级高的覆盖优先级低的,最大的为优先级最高)。
  • 生命周期函数不会相互覆盖,而是在对应触发时机被逐个调用:

    • 对于不同的生命周期函数之间,遵循组件生命周期函数的执行顺序;
    • 对于同种生命周期函数,遵循如下规则:
      • behavior 优先于组件执行;
      • 子 behavior​ 优先于父 behavior 执行;
      • 靠前的 behavior​ 优先于靠后的 behavior 执行。
  • 如果同一个 behavior 被一个组件多次引用,它定义的生命周期函数只会被执行一次。

网络请求

  • 使用GET/POST对远端服务器进行数据交换
  • 微信只能使用https类型的接口
  • 必须将接口的域名添加到信任列表中

怎么添加信任域名:

查看:

image

开通:

image

image

域名要求:

  • 域名只允许https协议,不能使用IP地址/localhost,必需经过ICP备案

开发阶段不使用HTTPS域名:

image

  • 设置后可以使用http协议,只能在开发环境使用

GET-POST-请求

  • 微信有一个顶级对象wx不需要声明,全局就可以调用

​GET请求​

<!--wxml-->
<button bind:tap="getInfo">GET请求</button>

//JS Page({ getInfo(){ wx.request({ wx.request方法只能写在函数内 url:
'https://www.escook.cn/api/get', 请求的地址 method:"GET", 发起请求的方式 data:{
发起请求时携带的数据 name:"xinp", age:20 }, success:(res) => {
success代表回调函数(执行完某个方法后发起的函数)=> 是箭头函数 console.log(res);
} }) } })

参数 => {函数体}:这是一个箭头函数,将参数放入函数内

​POST请求​

  • 将method换成POST即可
<!--wxml-->
<button bind:tap="getInfo">GET请求</button>

//JS Page({ getInfo(){ wx.request({ wx.request方法只能写在函数内 url:
'https://www.escook.cn/api/get', 请求的地址 method:"POST", 发起请求的方式 data:{
发起请求时携带的数据 name:"xinp", age:20 }, success:(res) => {
success代表回调函数(执行完某个方法后发起的函数)=> 是箭头函数 console.log(res);
} }) } })

如果再请求连接使用GET提交部分参数时使用​ ​${变量值}​ ​来替换

示例:

Page({ data:{ name:"xinp" }, onTitt(){ wx.request({ url:
'https://xin-p.top/${this.data.name}', }) } })

NPM

  • npm就是导入别人已经做好的UI结构或者是库
  • 限制:不支持依赖Node.js的包,不支持依赖浏览器内置对象的包,不支持C++插件包

Vant Weapp-UI库

安装:

  • 在微信小程序的项目目录创建npm管理包:在有app.json​的目录使用命令窗口:npm init -y进行npm项目的初始化

    image

  • 使用命令:npm i vant-weapp -S --production安装库

  • 微信-工具-构建npm

    image

  • 修改app.js:去掉 "style": "v2",(Vant Weapp是基于基础组件库来修改的需要去除)

  • 每次安装都需要重新构建npm(会将node_modules的工具构建入miniprogram_npm目录内):可以先删除miniprogram_npm再构建

使用:

  • 在app.json/对应页面.json​声明新的节点:usingComponents在里面声明需要使用的组件

    "usingComponents": { "van-button": "vant-weapp/button" }

自定义CS覆盖

  • 需要在对应的JS文件内配置options​节点styleIsolation: 'shared'
Component({ options: { styleIsolation: 'shared', }, })

数据共享

  • 解决组件之间的数据

  • 在小程序中,可使用 mobx-miniprogram​ 配合 mobx-miniprogram-bindings 实现全局数据共享。其中:

    • mobx-miniprogram 用来创建 Store 实例对象
    • mobx-miniprogram-bindings 用来把 Store 中的共享数据或方法,绑定到组件或页面中使用
    • 安装这两个包:npm install -save mobx-miniprogram mobx-miniprogram-bindings
  • 本质就是创建一个JS文件用来存储

怎么创建Store对象

  • 创建一个专门的文件夹来存放共享的数据,创建JS文件,导入mobx-miniprogram​中的observable
  • 如果需要初始数据可以直接写(如data一致)
import { observable } from "mobx-miniprogram" export const srore = observable({
name:"xinp" })

定义内部的计算属性

  • 如在数据变动时进行自动更新等
  • 需要使用get定义自定义方法,表明只读
import { observable } from "mobx-miniprogram" export const srore = observable({
name:"xinp", numA:1, numB:2, get add(){ return this.numA+this.numB } })

怎么更改内部的数据

  • 这里遵循JAVA中封装的思想,外部不能直接修改内部的变量,提供相应的方法来进行修改
  • 需要导入:mobx-miniprogram​中的action
  • 并使用action包裹函数
import { observable,action } from "mobx-miniprogram" export const srore =
observable({ numA:1, upNumA:action(function(step){
upNumA为自定义函数名,step为自定义接收的变量 this.numA = stop }) })

怎么在页面中使用

  • 在使用的界面JS文件中:导入mobx-miniprogram-bindings​中的createStoreBindings​方法;导入自定义的数据源import { 自定义名称 } from "相对路径"

  • 在JS文件的:onLoad​函数中使用createStoreBindings挂载数据

    onLoad(options){ this.自定义变量名 = createStoreBindings(this,{ 数据源,
    fields:[导入的变量属性/计算属性也属于属性], actions:[方法] }) },
  • 在HTML中使用与在本页面的JS文件定义的一致(本质与behaviors-共享无异),传参可以参考WXJS-事件绑定-事件传参的介绍,接收到的数据为:e.currentTarget.dataset.参数

  • 在页面的onUnload​函数清理残留:this.刚才定义的接收变量.destroyStoreBindings()

// /Stop/stop.js import { observable,action } from "mobx-miniprogram" export
const store = observable({ name:"xinp", numA:1, numB:2, get add(){ return
this.numA+this.numB }, upNumA:action(function(e){ const step =
parseInt(e.currentTarget.dataset.step); this.numA = step }) })

<!--pages/temp/temp.wxml-->
<text class="Ctext">这里是首页</text>
<view>姓名:{{name}}</view>
<view>{{numA}}+{{numB}}={{add}}</view>
<button bind:tap="upNumA" data-step="10">设置numA为10</button>

// pages/temp/temp.js import { createStoreBindings } from
"mobx-miniprogram-bindings" import { store } from "../../Store/store" Page({
onLoad(options){ this.storeBindings = createStoreBindings(this,{ store,
fields:["numA","numB","name","add"], actions:["upNumA"] }) }, onUnload(){
this.storeBindings.destroyStoreBindings() } })

怎么在组件中使用

  • 使用与在页面的使用基本一致,都需要导入工具和数据源
  • 需要在:​behaviors​​内导入工具,与data同级声明storeBindings​节点,接收三个参数(数据源,变量/属性,方法)
<!--components/test/test.wxml-->
<view>这里是组件</view>
<view>{{numA}}+{{numB}}={{add}}</view>
<button bind:tap="upNumA" data-step="10">A数字为10</button>

// components/test/test.js import {storeBindingsBehavior} from
"mobx-miniprogram-bindings" import {store} from "../../Store/store" Component({
behaviors: [storeBindingsBehavior], storeBindings: { store, 数据源 fields: {
导入的属性/变量 numA: "numA", 在组件内使用的变量名:导入数据源中定义的变量名
numB: "numB", add: "add", }, actions:{ 导入的方法 upNumA:"upNumA"
可以直接调用或者通过this同级调用(同级调用传递过来的数据为e.target.dataset.变量名)
} }, }) // /Stop/stop.js import { observable,action } from "mobx-miniprogram"
export const store = observable({ name:"xinp", numA:1, numB:2, get add(){ return
this.numA+this.numB }, upNumA:action(function(e){ const step =
parseInt(e.currentTarget.dataset.step); 在数据源处接收数据 this.numA = step })
})

分包

  • 按需加载需要的页面资源
  • 分为主包和次包:主包一般为小程序的首页和导航栏公共资源,次包就是细化的页面和私有页面
  • 主包加次包最多16M,每个包最多2M
  • 主包无法引用分包的资源,分包之间不能相互引用,在subpackages中声明的节点外的资源都属于主包,分包之间不能相互嵌套
  • 分包的文件夹将于主包同级

创建分包

  • 在app.json​声明​subPackages​​节点,有几个分包就有几个{}
  • 在{}​内:root​用于指明分包的文件夹名称,pages​指明页面与主包​pages​声明的一致,可以使用name声明别名

image

{ "pages": [ 这里时主包页面 "pages/test/test", ], "subPackages": [
这里是分包页面 { "root": "packageA", 分包的文件夹名 "pages": [ 分包的页面
""pages/cat/cat"" 分包的页面是 ] }, { "root": "packageB", "name": "paB",
分包的别名 "pages": [ "pages/apple/apple" ] } ], }

独立分包

  • 另类的主包,在不需要主包向独立打开某个页面时使用,他不需要主包来进行唤醒
  • 资源不能被主包引用资源,不能使用主包的资源
  • 与普通分包的唯一区别是在声明分包时使用 "independent": true配置项
{ "subPackages": [ { "root": "packageB", "pages": [ "pages/index/index" ],
"independent": true } ] }

分包预下载

  • 在进入某些页面时,预下载某些分包
  • 在app.json​进行配置preloadRule节点
  • 分包预下载的总大小为2M

示例:

{ "preloadRule": { "pages/test/test":{ 这里是进入某个路径开始预下载 "network":
"all", 这里是网络类型,all是任意网络都进行预下载,wifi是仅在wifi下进行预下载
"packages": ["packageB"] 这里填的是分包的root名称/name的名称 } }, }

‍

‍

页面跳转-导航

  • 页面之间进行跳转

跳转到下一级:

  • <navigator>组件跳转到指定的taBar页面,需要指定url与open-type属性
  • url​:跳转到的页面,必须以/开头
  • open-type​:跳转的方式,跳转到taBer页面必须使用switchTap​,跳转到普通的非taBer页面使用navigate属性(可以省略)

示例:

<!--pages/temp/temp.wxml-->
<text>这里是首页</text>

<navigator url="/pages/test/test" open-type="switchTab"
  >跳转到测试taBer页面</navigator
>
<navigator url="/pages/test1/test1" open-type="navigate"
  >跳转到非taBer页面</navigator
>

<!--wxml-->
<text>这里是测试taBer</text>

<!--pages/test1/test1.wxml-->
<text>这里是非taBer页面</text>

跳转到上一级:

  • 使用<navigator>组件,不用写url
  • open-type​:的值为navigateBack​,并使用delta="值"​指定后退的层数(如果后退层数为1可以不写delta的值)

示例:

<!--pages/test1/test1.wxml-->
<text>这里是非taBer页面</text>
<navigator open-type="navigateBack" delta="1">回退</navigator>

导航传参:

  • url​:表示路径,路径与参数之间使用?​隔开,键与值使用=​连接,不同参数使用&连接
  • 怎么接收参数,请参看onLoad部分
<navigator url="/pages/test1/test1?name=xinp&age=20">点击跳转</navigator>

wx.switchTab-编程式跳转

跳转tabBer页面:

  • ​wx.switchTab(参数)​ :方法进行页面跳转
属性 类型 必选 说明
url string 是 需要跳转的taBer页面,路径后不能带参数
success 函数 否 执行成功的回调函数
fail 函数 否 执行失败的回调函数
complete 函数 否 执行后调用函数(无论失败成功)

示例:

<!--pages/temp/temp.wxml-->
<text>这里是首页</text>
<navigator url="/pages/test/test" open-type="switchTab"
  >跳转到测试taBer页面</navigator
>

<!--test.wxml-->
<text>这里是测试taBer</text>
<button bind:tap="back">回退</button>

//test.JS Page({ back(){ wx.switchTab({ url: '/pages/temp/temp', success(){
console.log("执行回退成功"); } }) } })

wx.navigateTo-编程式跳转

跳转到非tabBer页面

  • ​wx.navigateTo(参数)​ :
属性 类型 必选 说明
url string 是 需要跳转的taBer页面,路径后不能带参数
success 函数 否 执行成功的回调函数
fail 函数 否 执行失败的回调函数
complete 函数 否 执行后调用函数(无论失败成功)

示例:

<!--test.wxml-->
<text>这里是测试taBer</text>
<button bind:tap="back">跳转到非tabBer页面</button>

//test.JS Page({ back(){ wx.navigateTo({ url: '/pages/test1/test1', }) } })

<!--pages/test1/test1.wxml-->
<text>这里是非taBer页面</text>

编程式传参:

  • 与navigator传参方式相同
  • 怎么接收参数,请参看onLoad部分
<!--pages/temp/temp.wxml-->
<text>这里是首页</text>
<button bind:tap="gotoTset1">跳转到Test</button>

<!--pages/temp/temp.wxml-->
<text>这里是首页</text>
<button bind:tap="gotoTset1">跳转到Test</button>

wx.navigateBack-编程式回退

  • 回退到上级或上几级
  • wx.navigateBack(参数):
属性 类型 默认 必选 说明
delta 数字 1 否 跳转为上几级,大于最大深度跳转到首页
success 函数 否 执行成功的回调函数
fail 函数 否 执行失败的回调函数
complete 函数 否 执行后调用函数(无论失败成功)

示例:

<!--test.wxml-->
<text>这里是测试taBer</text>
<button bind:tap="back">跳转到非tabBer页面</button>
//test.JS Page({ back(){ wx.navigateTo({ url: '/pages/test1/test1', }) } })

<!--pages/test1/test1.wxml-->
<text>这里是非taBer页面</text>
<button bind:tap="gotoBack">回退上一级</button>
//test1.JS Page({ gotoBack() { wx.navigateBack({ delta:1 }) }, })

wx.setNavigationBarTitle-动态设置标题

  • 只能在生命周期函数onReady() {}后写

属性:

属性 类型 默认值 必填 说明
title string 是 页面标题
success function 否 接口调用成功的回调函数
fail function 否 接口调用失败的回调函数
complete function 否 接口调用结束的回调函数(调用成功、失败都会执行)

示例:

<!--test.wxml-->
<text>这里是测试taBer</text>
<button bind:tap="onTitt">更改标题</button>

//test.JS Page({ onTitt(){ wx.setNavigationBarTitle({ title: 'Ab' }) } })

页面交互

wx.showLoading-显示提示框

  • 显示提示框,用于等待状态,提示框并不会主动关闭,需要使用​hideLoading​进行主动关闭

image

属性 类型 默认 必填 说明
title string 是 提示的内容
mask boolean false 否 是否显示透明蒙层,防止触摸穿透
success function 否 接口调用成功的回调函数
fail function 否 接口调用失败的回调函数
complete function 否 接口调用结束的回调函数(调用成功、失败都会执行)

示例:

<!--pages/test1/test1.wxml-->
<button bind:tap="onBut">提示框模拟</button>

// pages/test1/test1.js Page({ onBut(){ wx.showLoading({ title: '提示框', }),
setTimeout(()=>{ setTimeout用于延迟触发 wx.hideLoading() 关闭提示框 },2000) },
})

wx.showToast-消息提示框

  • 默认1.5S后自动消失

属性:

属性 类型 默认值 必填 说明 最低版本
title string - 是 提示的内容 -
icon string success 否 图标 -
image string - 否 自定义图标的本地路径,image 的优先级高于 icon 1.1.0
duration number 1500 否 提示的延迟时间 -
mask boolean false 否 是否显示透明蒙层,防止触摸穿透 -
success function - 否 接口调用成功的回调函数 -
fail function - 否 接口调用失败的回调函数 -
complete function - 否 接口调用结束的回调函数(调用成功、失败都会执行) -

示例:

image

<!--test.wxml-->
<text>这里是测试taBer</text>
<button bind:tap="onTitt">提示框</button>

//S Page({ onTitt(){ wx.showToast({ title: '这是演示提示框', }) } })

API

事件监听

  • 以on开头,监听事件的触发(窗口的变换等)

onLoad-加载页面触发

  • 写在该函数内的方法会自动在启动时自动将在方法(如数据列表请求等)
// js Page({ onLoad(options) { }, )}

怎么调用同级的方法

//JS Page({ getInfo(){console.log("你好");}, onLoad(options) { this.getInfo() },
})

接收路径跳转的传参:

  • options里就包含了传递过来的参数
  • 声明式/编程式都可以
<!--pages/temp/temp.wxml-->
<text>这里是首页</text>
<button bind:tap="gotoTset1">跳转到Test</button>

// pages/temp/temp.js Page({ gotoTset1(){ wx.navigateTo({ url:
'/pages/test1/test1?name=xinp&age=20', }) } }) // pages/test1/test1.js Page({
data: { query: [] }, onLoad(options) { console.log(options); this.setData({
query: options 将传来的参数转存到自定义的query数组中 }) }, }) {name: "xinp",
age: "20"}使用options.name得到xinp

onPullDownRefresh-下拉刷新监听事件

  • 条件:开启页面的下拉刷新(可看页面和全局JSON部分),只建议为单独的页面开始下拉刷新。在json​中设置"enablePullDownRefresh":true
  • 当下拉刷新后会触发onPullDownRefresh函数中的方法

示例:

// js Page({ onPullDownRefresh() { console.log("触发了下拉刷新"); }, })

wx.stopPullDownRefresh-怎么停止下拉刷新行为

  • 在下拉刷新后并不会自动停止,还是保持下拉状态
  • 在下拉刷新行为结束后使用:wx.stopPullDownRefresh({})即可停止下拉刷新行为

示例:

// js Page({ onPullDownRefresh() { console.log("触发上拉刷新");
wx.stopPullDownRefresh({}) }, })

设置按需调用函数

  • 可以再自定义函数中设置一个参数,并使用&&判断是否执行

示例:

<!--test.wxml-->
<text>这里是测试taBer</text>
<button bind:tap="onSh">提示框</button>

//test.JS Page({ onSh(){ this.onTitt(()=>{
这里会见{}内的内容作为函数传入调用的函数中,再不需要时可以不传入 wx.showToast({
title: '这是演示提示框', }) }) }, onTitt(title){ 判断title是否有内容,有运行
title && title() } })

onReachBottom-上拉触底事件

  • 一般用于上拉加载更多的数据,当上拉时会触发onReachBottom中的函数方法
  • 每次到达设置上拉触底事件都会触发一次该函数,在有网络请求的情况下需要对一定时间内的请求进行限制。
  • 多长距离触发:在json内设置onReachBottomDistance(具体参看页面与全局JSON)
// js Page({ onReachBottom() { console.log("触发了上拉触底事件"); }, })

示例:包含-短时间内控制请求次数-触底触发

<!--pages/test1/test1.wxml-->
<view>这里是非taBer页面</view>
<view>下拉触底刷新数据</view>
<view wx:for="{{myArray}}" wx:key="item">当前数字{{item}}</view>

// pages/test1/test1.js Page({ data: { myArray:[], 存放遍历的数据 number:0 },
addNumber() { 生成20个数字 const currentArray = this.data.myArray;
获取原本的数组给新的数组 let newNumber = this.data.number + 1;
获取原本的标记的数字 const newArray = [...currentArray];
复制原本的数组到新的数组,...是展开运算符(将数组内的元素展开成单独的元素) for
(let i = 0; i < 20; i++) { newArray.push(newNumber);
使用push将新生成的数字添加到新的数组中 newNumber++; } this.setData({ myArray:
newArray, 覆盖原本的数据 number: newNumber }); }, onLoad(options) {
生命周期函数--监听页面加载 this.addNumber(); this.addNumber(); },
onPullDownRefresh() { }, onReachBottom() { 页面上拉触底事件的处理函数
this.addNumber(); }, })

对上拉触底事件进行节流设置

  • 再data中定义一个变量来记录当前是否可以进行数据请求,为ture(可以)false(不行)

示例:

<!--pages/test1/test1.wxml-->
<view>这里是非taBer页面</view>
<view>下拉触底刷新数据</view>
<view wx:for="{{myArray}}" wx:key="item">当前数字{{item}}</view>

// pages/test1/test1.js Page({ data: { myArray:[], number:0, onLing:true },
addNumber() { this.setData({ 将请求设置为false onLing:false }) setTimeout(()=>{
模拟请求延迟2S const currentArray = this.data.myArray; let newNumber =
this.data.number + 1; const newArray = [...currentArray]; for (let i = 0; i <
20; i++) { newArray.push(newNumber); newNumber++; } this.setData({ myArray:
newArray, number: newNumber }); },2000) this.setData({
请求结束,将请求设置为true,可以进行请求 onLing:true }) }, onLoad(options) {
开始加载数据 this.addNumber(); this.addNumber(); }, onReachBottom() {
页面触底触发事件 if(this.data.onLing){ 对onLing进行判断 this.addNumber(); }else{
return } }, })

同步

  • 以Sync结尾,可任意通过函数返回值获取(向本地存储写入内容)

Pormise-改造

  • 将同步API改造成为异步API,提高代码的可阅读性
  • 依赖第三方npm包(怎么npm请参考npm部分内容):npm i--save miniprogram-api-promise@版本​(示例:npm i--save [email protected])
  • 每次安装都需要重新构建npm(会将node_modules的工具构建入miniprogram_npm目录内):可以先删除miniprogram_npm再构建

改造app.js:

//导入包 import { promisifyAll } from 'miniprogram-api-promise' //自定义对象
const wxp = wx.p = {} // 将微信经过promisifyAll改造,使用wxp即可调用
promisifyAll(wx, wxp) App({})

调用改造后的API

  • 使用方法与原来的一致,只是将wx对象改为刚才自定义的方法
正常使用wx对象: wx.request({ url: 'url', }) 改造后: wx.p.request({ url: 'url',
})

异步

  • 类似于jQuery中的$.ajax(options)函数(发起网络请求)

云开发

  • 初始化云环境app.js中进行定义
// app.js
App({
  onLaunch: function () {
    wx.cloud.init({
      // env 参数说明:env 参数决定接下来小程序发起的云开发调用(wx.cloud.xxx)会默认请求到哪个云环境的资源,此处请填入环境 ID, 环境 ID 可打开云控制台查看,如不填则使用默认环境(第一个创建的环境)
      env: "",
      traceUser: true,
    });
  },
});

云数据库

控制台创建

image

云开发–数据库

  • 集合就是传统数据库的表
  • 记录就是添加的记录

调用

初始化连接数据库

const 自定义名称 = wx.cloud.database() 后面关于数据库的操作都需要这个变量
与Page平齐或写在onLoad(options)页面加载函数内

const db = wx.cloud.database()

连接数据库

使用 collection("数据库的名称") 来指定要访问的数据库

db.collection("demolist")

查询

  • 获取数据库的全部内容

    • 使用get

    • db.collection("demolist").get({
      	success:res=>{ 这里是回调函数,用于显示返回的信息
      		console.log(res);
      	}
      })
  • 获取指定ID的数据

    • 使用doc("要查询的ID").get()

    • db.collection("demolist")
        .doc("a6ec30486809ef8301c3f31c06f3855b")
        .get({
          success: (res) => {
            console.log(res);
          },
        });
  • 获取数据库的记录条数:​count()​

    <!--pages/index/index.wxml-->
    <button bind:tap="onConst">记录条数</button>
    
    // pages/index/index.js
    const db = wx.cloud.database()
    Page({
      onConst(){
        db.collection("demolist").count().then(res=>{
            console.log(res);
        })
      },
    })
  • ‍

可以进行链式调用

  • 正确结果:使用then(res=>{})​来代替success:res=>{}
db.collection("demolist")
  .doc("a6ec30486809ef8301c3f31c06f3855b")
  .get()
  .then((res) => {
    console.log(res);
    this.setData({
      user: res.data,
    });
  })
  .then((res) => {
    console.log("完成");
  });
  • 错误结果:使用.catch(err=>{})
db.collection("demolist")
  .doc("a6ec30486809ef8301c3f31c06f3855b")
  .get()
  .then((res) => {
    console.log(res);
    this.setData({
      user: res.data,
    });
  })
  .catch((res) => {
    console.log("错误");
  });

示例:

image

<!--pages/index/index.wxml-->
<button bind:tap="getDate">点击访问</button>

// JS部分
  getDate(){
    db.collection("demolist").get({
        success:res=>{
            console.log(res);
        }
    })
  }

查询指令-筛选

  • 就是条件筛选,在get​前添加筛选条件where({条件})
查询指令 说明
eq 等于
neq 不等于
lt 小于
lte 小于或等于
gt 大于
gte 大于或等于
in 字段值在给定数组中
nin 字段值不在给定数组中

示例:

image

<!--pages/index/index.wxml-->
<button bind:tap="getDate">点击访问</button>
<view wx:for="{{user}}" wx:key="index">{{item.name}}</view>

// pages/index/index.js
const db = wx.cloud.database()
Page({
  data: {
    user:""
  },
  getDate(){
    db.collection("demolist").where({ 条件筛选名字xinp
        name:"xinp"
    }).get().then(res=>{
        console.log(res.data);
        this.setData({
            user:res.data
        })
    })
  },
})

查询指令-返回指定条数记录

  • 使用:limit(条数)
  • 在小程序端一次最多20条,云函数一次1000条

示例:

<!--pages/index/index.wxml-->
<button bind:tap="getData">点击获取记录</button>

// pages/index/index.js
const db = wx.cloud.database()
Page({
  getData(e){
    db.collection("demolist").limit(1).get().then(res=>{
        console.log(res);
    })
  },
})

查询指令-排序

  • 使用:orderBy("根据谁排序","升序/降序")​,不写为升序asc​,降序为desc
  • 小程序端20条,云函数1000条

示例:

  getData(e){
    db.collection("demolist").orderBy("name","asc").get().then(res=>{
        console.log(res);
    })
  }

查询指令-页数

  • 从第几条记录开始返回,使用:skip(条数)

示例:

  getData(e){
    db.collection("demolist").skip(2).get().then(res=>{
        console.log(res);
    })
  }

查询指令-查询记录的特定部分

  • 查询记录的某个字段(标题/年龄其他不要):field({字段:true,...})
  getData(e){
    db.collection("demolist").field({name:true}).get().then(res=>{
        console.log(res);
    })
  }

高级查询—多条件command

  • 需要创建对象:db.command​(const 自定义变量 = db.command)
  • 需要配合:where进行使用
  • 具体的方法可参考官方文档:Command文档 云开发-SDK-数据库-Command

示例:

  getData(e){
    db.collection("demolist").where({
        name:_.neq("xinp") 不等于
    }).get().then(res=>{
        console.log(res);
    })
  }

添加

  • 使用add({ data:{} })进行添加,添加成功将会返回该记录的ID
<!--pages/index/index.wxml-->
<button bind:tap="addDate">添加数据</button>

// pages/index/index.js
const db = wx.cloud.database()
Page({
  addDate(){
    db.collection("demolist").add({
        data:{
            name:"xinzhu",
            sum:["1","2"]
        }
    }).then(res=>{console.log("添加成功");})
  },
})

添加的数据:

image

这里自动添加的_openid的作用是为了身份识别,是谁创建上传的

更新

  • 更新添加:需要使用update(data:{}),在修改前需要使用条件筛选修改的记录,可以更新和添加记录
  • 在客户端只能使用doc("ID")​修改单条记录,在云函数可额外使用where(筛选条件)修改多条记录
  • 替换原本的记录:使用set(data:{})
<!--pages/index/index.wxml-->
<form bindsubmit="upData">
    <input name="name" placeholder="输入名字"></input>
    <button type="primary" form-type="submit">更新</button>
    <button form-type="reset">重置</button>
</form>

// pages/index/index.js
const db = wx.cloud.database()
Page({
  upData(e){
    const {name} = e.detail.value;
    db.collection("demolist").doc("b01319476809fe6d01c81aee3fa81c83").update({
       data:{
           name:name
       }
    }).then(res=>{
        console.log(res);
    })
  },
})

删除

  • 需要使用remove()
  • 在客户端只能使用doc("ID")​删除单条记录,在云函数可额外使用where(筛选条件)删除多条记录
<!--pages/index/index.wxml-->
<form bindsubmit="remData">
    <button type="primary" form-type="submit">删除记录</button>
</form>

// pages/index/index.js
const db = wx.cloud.database()
Page({

  /**
   * 页面的初始数据
   */
  data: {
    user:""
  },
  remData(e){
    const {name} = e.detail.value;
    db.collection("demolist").doc("b01319476809fe6d01c81aee3fa81c83").remove().then(res=>{
        console.log(res);
    })
  },
})

监控

  • 在数据库变换时将会触发:watch(onChange:res=>{成功回调},onError:err=>{失败回调}),两个回调必须书写
  • 一般写在:声明函数onLoad(options)中

image

docChanges是当前的,docs是最新变化的

<!--pages/index/index.wxml-->
<form bindsubmit="addData">
    <input name="name" type="text"/>
    <button form-type="submit">提交</button>
</form>
<view wx:for="{{userArr}}" wx:key="index">{{index+1}}记录:{{item.name}}</view>

// pages/index/index.js
const db = wx.cloud.database()
Page({
  data: {
    userArr:""
  },
  addData(e){
    db.collection("demolist").add({
        data:e.detail.value
    }).then(res=>{
        console.log("添加成功");
    })
  },
  onLoad(options) {
    db.collection("demolist").watch({
        onChange:res=>{
            this.setData({
                userArr:res.docs
            })
        },
        onError:err=>{
            console.log("失败");
        }
    })
  },
})

云函数

  • 将本地的JS处理逻辑上传到云端,进行调用即可(云函数的权限会更大)

初始化

  • 修改project.config.json​文件,新增 cloudfunctionRoot 字段,指定本地已存在的目录作为云开发的本地根目录

    {
       "cloudfunctionRoot": "cloudfunctions/"
    }
  • 创建云函数

    image

  • 上传云函数

    image

初始化的三个云函数文件

  1. config.json(云函数配置文件):用于配置云函数调用微信开放接口的权限

    {
      "permissions": {
        "openapi": [
          // 这里可以添加需要调用的微信开放接口名称
        ]
      }
    }
  2. index.js(云函数入口文件)

    const cloud = require("wx-server-sdk");
    // 初始化云环境,使用当前小程序的云开发环境
    cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV });
    // 云函数入口函数
    exports.main = async (event, context) => {
      // 获取微信上下文信息
      const wxContext = cloud.getWXContext();
      // 返回用户信息和事件参数
      return {
        event, // 客户端调用时传递的参数
        openid: wxContext.OPENID, // 用户的openid
        appid: wxContext.APPID, // 小程序appid
        unionid: wxContext.UNIONID, // 用户的unionid(需满足条件)
      };
    };
  3. package.json(项目配置文件)

    {
      "name": "getData",    // 云函数名称
      "version": "1.0.0",   // 版本号
      "description": "",    // 项目描述
      "main": "index.js",   // 入口文件
      "scripts": {          // npm脚本命令
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "author": "",         // 作者信息
      "license": "ISC",     // 开源协议
      "dependencies": {     // 依赖包
        "wx-server-sdk": "~3.0.1" // 微信云函数SDK
      }
    }

示例:将数据库查询写成云函数

getData云函数:
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) // 使用当前云环境
const db = cloud.database()
// 云函数入口函数
exports.main = async (event, context) => {
    try {
        const res = await db.collection("demolist").get()
        return res.data
      } catch (err) {
        console.error("数据库查询失败", err)
        return { error: "查询失败", details: err }
      }
}

调用:
  getYun(){
    wx.cloud.callFunction({
        name:"getData"
    }).then(res=>{
        console.log(res);
    })
  }

编写

  • 在云函数不需要使用wx.这个顶级对象
  • 云函数的写法与正常JS写法一致
// 云函数入口文件
const cloud = require("wx-server-sdk");

cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }); // 使用当前云环境

// 云函数入口函数
exports.main = async (event, context) => {
  try {
    在这里写处理方法和返回;
  } catch (err) {
    这里写错误;
  }
};

传递参数

  • 前端传递过来的参数都存储在event​中,在data中的数据直接.变量名即可取出

示例:

云函数:
// 云函数入口文件
const cloud = require('wx-server-sdk')

cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) // 使用当前云环境
const db = cloud.database()

// 云函数入口函数
exports.main = async (event, context) => {
    return await db.collection(event.dbname).get()
}

调用:
  getYun(){
    wx.cloud.callFunction({
        name:"getData",
        data:{
            dbname:"demolist"
        }
    }).then(res=>{
        console.log(res);
    })
  }

调用

  • 需要使用wx.cloud.callFunction({})
  • 需要传递的参数:必写:name:"云函数的名字"​,可选:data:{需要传递给云函数的数据}
  getYun(){ 这是一个自定义方法
    wx.cloud.callFunction({
        name:"getData",
        data:{   }
    }).then(res=>{
        console.log(res);
    })
  }

云存储

  • 将图片/视频等文件上传到云端存储,方便随时调用
  • 使用:wx.cloud.uploadFile({})
  • cloudPath​指定云端的地址(image/${Date.now()}.jpg​ 要使用函数,变量需要使用数字1旁边的单引号使用${变量名})
  • filePath指定本地文件的地址

示例:

  async getYun(){ 自定义函数async异步用于处理await异步延迟的问题
    const res = await wx.chooseMedia({}) 获取图片得到本地地址
    const path = res.tempFiles[0].tempFilePath 本地地址提取
    wx.cloud.uploadFile({ 上传函数
        cloudPath:`image/${Date.now()}.jpg`,  云端地址
        filePath:path  本地地址
    }).then(res=>{console.log("上传成功");})
  }

进度

02-配置uni-app

‍