微信小程序
一、基础
1、项目目录
全局配置项:
(1)app.js
类似于base.js
,它是项目的全局js文件
(2)app.json
整体配置项:
pages
:页面路径列表:写上路径之后会自动创建文件夹
tabBar
:导航栏配置(底部或者顶部)
window
:
enablePullDownRefresh
:是否开启下拉刷新
"tabBar": {
"selectedColor":"#00f",
"list": [{
"pagePath": "pages/index/index",
"iconPath":"img/img1.png",
"selectedIconPath":"img/img11.png",
"text": "首页"
}, {
"pagePath": "pages/serve/index",
"iconPath":"img/img2.png",
"selectedIconPath":"img/img22.png",
"text": "服务"
}]
},
2、文档结构
(1).wxml
文件类似于html文件,.wxss
文件类似于css文件
.wxss
使用flex
布局
(2)在js文件中
// pages/about/index.js
Page({
/**
* 页面的初始数据
*/
data: {
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
})
(3)引入img
文件夹
在项目中引入img文件夹,不能直接复制到微信小程序中,要在windows的项目目录中复制进去
(4)新建子页
在tab切换页里新建子页:
1)子页也建在父页的文件夹中
2)在
app.json
全局配置的pages
中写上子页路径即可"pages":[ //原来的页面为index,建立子页,只需在相同目录起其他名字即可 "pages/about/index", "pages/about/ourselves", "pages/about/advantage", "pages/about/contact", "pages/serve/index" ],
3)子页跳转方式
标签跳转和js跳转
标签跳转:组件=>导航=>
navigator
组件标签js跳转:API=>路由=>
wx.navigateTo(Object object)
(5)template模板
便于多次复用
1)在目录中新建目录temp
2)新建.wxml
文件(模板文件)
3)在.wxml
文件中使用template
标签定义模板(一个文件里可以有多个template模板,name不同即可)
<template name="mwyswi1">
<swiper
autoplay="{{swienv.autoplay}}"
indicator-dots="{{swienv.indicator_dots}}"
indicator-active-color="{{swienv.indicator_active_color}}"
circular="{{swienv.circular}}"
indicator-color="{{swienv.indicator_color}}"
>
<swiper-item wx:for="{{swienv.imgSrc}}">
<image mode="widthFix" src="{{item}}"></image>
</swiper-item>
</swiper>
</template>
4)在.wxml
使用模板
先引入,再使用
通过is
值等于name值使用组件
通过data
属性向模板中传递参数
<!-- 导入模板 -->
<import src="../temp/swiperTemp.wxml"> </import>
<!-- 使用模板 -->
<template is="mwyswi1" data="{{swienv}}"></template>
<!-- 传值的时候可以解构一下,模板中的参数就可以不使用对象名 -->
<template is="mwyswi1" data="{{...swienv}}"></template>
(6)自定义组件
1)在项目中新建文件夹,专门用于放自定义组件
2)右键新建component组件
3)在其他组件中使用自定义的组件
在要使用的页面的.json配置文件中的usingComponents
中配置路径
{
"usingComponents": {
"my":"../com/my"
}
}
4)引用组件时候传递参数
接收传递的参数,需要先在my.js文件中properties
配置
properties: {
user:{
type:"String",
//如果不传参数时,则value为默认值
value:"张三"
}
},
.wxml
中通过属性传递参数
<my user="lyl"></my>
<!-- 此时user显示的是lyl-->
3、组件
(1)view
视图容器
view
<view hover-class="lyl"></view>
match-media(媒体查询)
<match-media min-width="300" max-width="600">
<view>当页面宽度在 300 ~ 500 px 之间时展示这里</view>
</match-media>
movable-area与 movable-view
可移动区域,与可移动试图容器
<movable-area>
<movable-view direction="all" inertia>text</movable-view>
</movable-area>
page-container与 share-element
页面容器与共享元素(设置假页,类似弹出的模态框效果)
使用时需在当前页放置
share-element
组件,同时在page-container
容器中放置对应的share-element
组件,对应关系通过属性值key
映射。
<share-element key="motal" transform="true" bindtap="showmodalDemo">弹框标题</share-element>
<page-container position="center" show="{{flag}}">
<share-element key="motal" transform="true">弹框标题</share-element>
<view>弹框内容,弹框内容弹框内容,弹框内容</view>
<button bindtap="showmodalDemo">关闭</button>
</page-container>
(2)基础内容
icon
图标
<icon type="success" size="50" color="#f00"></icon>
text
文本
<text>文本内容</text>
progress
进度条
<progress></progress>
rich-text
富文本
可以渲染出传统的html标签
<rich-text nodes="{{htmlSnip}}"></rich-text>
js
const htmlSnip =
`<div class="div_class">
<h1>Title</h1>
<p class="p">
Life is <i>like</i> a box of
<b> chocolates</b>.
</p>
</div>
`
(3)媒体组件
image
:默认的图片的大小不会随着宽或高一个变,另一个响应的改变
需要设置mode
参数自适应mode="widthFix"
,宽度固定,高度自适应
音频组件audio
例子:
wxml
<audio id="myAu" controls
poster="{{poster}}"
name="{{name}}"
author="{{author}}"
src="{{src}}"
bindtimeupdate="audioTime"
>
</audio>
<slider bindchange="progessTab" value="{{val}}" max="{{max}}" min="0" />
<button bindtap="start">暂停/开始</button>
<button bindtap="reset">重新播放</button>
js
Page({
/**
* 页面的初始数据
*/
data: {
poster:"../../img/p1.jpg",
src:"http://dl.stream.qqmusic.qq.com/C4000013He501sSS0V.m4a?guid=8576720152&vkey=D5EB7D8C92BD70C7A4BD2A7B78D95D41293864B589FC4AE8F2C2DB1247E892115FC000D1037BECB44FF0BDC8C7B13801090A4DFB515BF1BD&uin=&fromtag=120032",
name:"The Story Never Ends",
author:"Lauv",
au:"",
flag:true,
max:0,
val:0
},
//开始、暂停播放
start(){
if(this.data.flag){
this.au.play()
this.data.flag = !this.data.flag
}else{
this.au.pause()
this.data.flag = !this.data.flag
}
},
//重新开始播放
reset(){
this.au.seek(0)
this.au.play()
this.data.flag = !this.data.flag
},
//设置进度条最大值,和进度条播放的当前值
audioTime(event){
console.log(event.detail)
// this.data.max = event.detail.duration;
// this.data.val = event.detail.currentTime;
this.setData({
val:event.detail.currentTime,
max:event.detail.duration
})
},
//进度条切换
progessTab(event){
console.log(event.detail)
this.au.pause()
this.au.seek(event.detail.value)
this.setData({
val:event.detail.value
})
this.au.play()
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
this.au = wx.createAudioContext('myAu')
}
})
视频组件video
this.vo = wx.createVideoContext('myVideo')
wxml
通过bindinput
获取input输入框的值
<video controls
id="myVideo"
src="http://wxsnsdy.tc.qq.com/105/20210/snsdyvideodownload?filekey=30280201010421301f0201690402534804102ca905ce620b1241b726bc41dcff44e00204012882540400&bizid=1023&hy=SH&fileparam=302c020101042530230204136ffd93020457e3c4ff02024ef202031e8d7f02030f42400204045a320a0201000400"
enable-danmu="{{danFlag}}"
danmu-list="{{danList}}"
>
</video>
<switch checked="{{danFlag}}" bindchange="switchChange"/><text>弹幕</text>
<input type="text" class="inp" value="{{word}}" bindinput="getWord"></input>
<button bindtap="sendText">发送</button>
js
//获取input的值
getWord(event){
console.log(event.detail.value);
var v=event.detail.value;
this.setData({
word:v
})
},
//得到随机颜色
getColor(){
var r = Math.floor(Math.random()*255)
var g = Math.floor(Math.random()*255)
var b = Math.floor(Math.random()*255)
var v = "rgb("+r+","+g+","+b+")"
return "rgb("+r+","+g+","+b+")"
},
//发送弹幕
sendText(){
var that = this;
console.log(this.data.word)
this.vo.sendDanmu({
text:that.data.word,
color:that.getColor()
})
this.setData({
word:""
})
},
//开关
switchChange(event){
console.log(event)
let v = event.detail.value
this.setData({
danFlag:v
})
},
(4)页面链接(navigator
)
<navigator url="跳转路径"></navigator>
(5)地图(map)
map组件的属性(用腾讯地图坐标拾取器获取坐标)
longitude
精度
latitude
纬度
scale
放大尺寸
markers
标记(需要的值为数组,每个数组内容为对象)
<map name="" longitude="" latitude="" ></map>
(6)swiper组件
<swiper></swiper>
每一项为<swiper-item></swiper-item>
<swiper
autoplay="{{swienv.autoplay}}"
indicator-dots="{{swienv.indicator_dots}}"
indicator-active-color="{{swienv.indicator_active_color}}"
circular="{{swienv.circular}}"
indicator-color="{{swienv.indicator_color}}"
>
<swiper-item wx:for="{{swienv.imgSrc}}">
<image mode="widthFix" src="{{item}}"></image>
</swiper-item>
</swiper>
(7)scroll-view(可滚动视图区域)
<scroll-view scroll-with-animation="true" scroll-x="true" scroll-left="{{le}}">
<view bindtap="navTap" data-ind="{{index}}" wx:for="{{classArr}}" class="nav {{curIndex == index ? 'on' : ''}}" >{{item}}</view>
</scroll-view>
(8)表单组件
input组件
input组件可以通过type指定调出的键盘类型
(9)底部操作菜单(action-sheet
)
<action-sheet hidden="">
<action-sheet-item>全部歌曲</action-sheet-item>
<action-sheet-item>猜你喜欢</action-sheet-item>
<action-sheet-cancel>取消</action-sheet-cancel>
</action-sheet>
(10)相机(camera)
<camera></camera>
相关接口
API=>媒体=>相机
**1)**创建上下文对象:wx.createCameraContext()
**2)**拍照CameraContext.takePhoto(Object object)
在
success
方法的res
中获取拍的照片的路径
**3)**录像CameraContext.startRecord(Object object)
4)将图片保存到相册(默认拍照的图片是不会保存到相册的)
API=>媒体=>图片
将图片保存到相册:
wx.saveImageToPhotosAlbum(Object object)
将从相册选择图片:
5)保存视频到相册
wx.saveVideoToPhotosAlbum(Object object)
(11)画布canvas
<canvas></canvas>
(12)button组件
4、基础语法
所有变量都要使用{{}}
包起来,无论是在文档中,还是作为属性
(1)for循环
默认遍历出来的值为item
,index
也可以直接写
<view wx:for="{{arr}}">{{item}},{{index}}</view>
遍历出来的值可以改名,将默认的item
改为其他名字(wx:for-item="x"
)
<view wx:for="{{arr}}" wx:for-item="x" wx:for-index="y">{{x}},下标为:{{y}}</view>
(2)if
条件为true则显示,为false则隐藏
<view wx:if="{{flag}}"></view>
<view wx:elif="{{flag}}"></view>
<view wx:else="{{flag}}"></view>
5、事件
(1)点击事件(bindtap
)
函数直接写在js文件的page({})
中,和data
并列
事件传参数
1)传参通过属性传参data-name="值"
(name是参数的名字)
2)在函数中通过event
接收参数
<view bindtap="jump" data-u="contact"></view>
通过event接收参数
jump(event){
console.log(event.currentTarget.dataset.u);
let u = event.currentTarget.dataset.u
wx.navigateTo({
url:u
})
},
6、接口(API)
(1)拨打电话接口
API=>设备=>电话
wx.makePhoneCall(Object object)
(2)页面跳转(路由)
wx.navigateTo(Object object)
注意:跳转路径不加文件后缀名
jump(){
wx.navigateTo({
url:"./contact"
})
},
(3)网络
API=>网络=>发起请求(wx.request
)
发起请求:
wx.request
:
调用自己的后台接口(要设置域名白名单,要是本地的则需要:点击详情=>本地设置=>不校验合法域名)
http://localhost:3000/details
注意:
给全局变量设置值,不能直接赋值,要使用**this.setData({变量名:值})
**
onLoad(options) {
let that=this;
wx.request({
url: 'http://localhost:3000/daily',
data:{
},
method:"POST",
success(res){
console.log(res)
//给全局变量赋值要使用this.setData()
that.setData({
myword:res.data.data[0].typeName
})
}
})
},
09_06
:模板,组件,假页(弹窗),swiper(滚动swiper与nav),音频,视频
(4)WXML
wx.creteSelectorQuery()
:获取界面上的节点信息(节点的宽,高等信息)
1)创建selector选择器对象
2)query.select('#the-id').boundingClientRect()
3)query.exec(function(res){...}
const query = wx.createSelectorQuery()
//select只能选一个
//selectAll可以选择多个
query.select('#the-id').boundingClientRect()
//query.selectViewport().scrollOffset()
query.exec(function(res){
res[0].top // #the-id节点的上边界坐标
res[1].scrollTop // 显示区域的竖直滚动位置
})
例子:导航栏顶部nav一直滚动显示第一个
//让scoll滚动,设置le的值
var that = this;
var allLe=0
const query = wx.createSelectorQuery()
query.selectAll('.nav').boundingClientRect()
query.exec(function(res){
console.log(res[0])
//核心:每次滚动的距离为index下标个宽度的nav相加
for(var i=0;i<ind;i++){
allLe += res[0][i].width
}
that.setData({
le:allLe
})
})
(5)录音
wx.getRecorderManager
onLoad(options) {
//获得录音对象
this.reVoice = wx.getRecorderManager();
this.innerAudioContext = wx.createInnerAudioContext({
useWebAudioImplement: true // 是否使用 WebAudio 作为底层音频驱动,默认关闭。对于短音频、播放频繁的音频建议开启此选项,开启后将获得更优的性能表现。由于开启此选项后也会带来一定的内存增长,因此对于长音频建议关闭此选项
})
},
//开始录音
makeVoice() {
this.reVoice.start()
},
//停止录制声音
stopVoice() {
let that = this;
this.reVoice.stop();
this.reVoice.onStop((res) => {
console.log('recorder stop', res.tempFilePath)
that.setData({
tempVoice:res.tempFilePath
})
})
},
//播放录音
showVoice() {
this.innerAudioContext.src = this.data.tempVoice;
console.log(this.innerAudioContext)
this.innerAudioContext.play() // 播放
},
(6)背景音频
背景音频与音频的区别与联系
(7)页面间跳转(路由)
对于可以传参的API,在相应的跳转页,接收参数
onLoad(options)生命周期函数中的options接收参数
(8)动画
API=>界面=>动画
wx.createAnimation(Object object)
1)创建动画
2)执行动画函数(要在结尾加.step()
避免下次执行不生效)
3)导出(export
)
4)在.wxml
中给要执行动画的组件设置animation
属性,属性值为export导出
showAni() {
//创建对象
let ani = wx.createAnimation({
duration: 3000
})
//执行动画(链式调用step)
ani.rotate(50).step();
//导出(export)
this.setData({
move: ani.export()
})
let that = this;
setTimeout(function () {
console.log("enter")
ani.rotate(0).step();
that.setData({
move: ani.export()
})
}, 4000)
},
wxml
<!-- 设置animation属性 -->
<view class="ani" animation="{{move}}"></view>
<button bindtap="showAni">执行动画</button>
(9)交互(提示弹框)
API=>界面=>交互
消息提示框wx.showToast(Object object)
模态对话框wx.showModal(Object object)
(10)导航栏
API=>界面=>导航栏
通过js控制导航栏
在当前页面显示导航栏加载动画:wx.showNavigationBarLoading(Object object)
(11)Tab Bar(显示未读消息小红点)
API=>界面=>Tab Bar
显示tabBar某一项的右上角的小红点:wx.showTabBarRedDot(Object object)
(12)数据缓存
API=>数据缓存
本地存储:wx.setStorage(Object object)
(13)开放接口(登录与获取用户信息)
登录: wx.login(Object object)
调用接口获取登录凭证(code)。通过凭证进而换取用户登录态信息,包括用户在当前小程序的唯一标识(openid)、微信开放平台帐号下的唯一标识(unionid,若当前小程序已绑定到微信开放平台帐号)及本次登录的会话密钥(session_key)等。用户数据的加解密通讯需要依赖会话密钥完成。
用户信息:wx.getUserProfile(Object object)
获取用户信息。页面产生点击事件(例如
button
上bindtap
的回调中)后才可调用,每次请求都会弹出授权窗口,用户同意后返回userInfo
。该接口用于替换wx.getUserInfo
wx.getUserProfile({
//desc必传
desc:"获取头像昵称",
success(res){
console.log(res);
}
})
(14)联系人
API=>设备=>联系人
拉取手机通讯录,选择联系人wx.chooseContact(Object object)
(15)获取手机号
获取手机号(只能企业版商户有获取的权限)
步骤:
(1)获取code
通过button组件的bindgetphonenumber
事件的detail获取code
<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">
获取手机号
</button>
getPhoneNumber(event){
console.log(event.detail)
}
(2)获取access_token
指南=>接口调用凭证
wx.request({
url:'https://api.weixin.qq.com/cgi-bin/token',
method:"GET",
data:{
grant_type:'client_credential',
appid:'自己的appid',
secret:'自己的密钥',
},
success(res){
console.log(res)
}
})
(3)通过code
和access_token
获取手机号
wx.request({
url: 'https://api.weixin.qq.com/wxa/business/getuserphonenumber',
method: "POST",
data: {
code: "",
access_token: ""
},
success(res){
console.log(res)
}
})
(1)获取code:
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.html
(2) 获取access_token:
https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/access-token/auth.getAccessToken.html
(3) 获取手机号:
https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/phonenumber/phonenumber.getPhoneNumber.html
申请测试号:
https://developers.weixin.qq.com/miniprogram/dev/devtools/sandbox.html
二、WXS语言
可内嵌在.wxml
WXS(WeiXin Script)是小程序的一套脚本语言,结合 WXML
,可以构建出页面的结构。
\1. WXS 不依赖于运行时的基础库版本,可以在所有版本的小程序中运行。
\2. WXS 与 JavaScript 是不同的语言,有自己的语法,并不和 JavaScript 一致。
\3. WXS 的运行环境和其他 JavaScript 代码是隔离的,WXS 中不能调用其他 JavaScript 文件中定义的函数,也不能调用小程序提供的API。
\4. WXS 函数不能作为组件的事件回调。
\5. 由于运行环境的差异,在 iOS 设备上小程序内的 WXS 会比 JavaScript 代码快 2 ~ 20 倍。在 android 设备上二者运行效率无差异。
//1)单个变量
<wxs module="m1">
var mes = "hello world!!!"
module.exports.mes = mes;
</wxs>
<view> {{m1.mes}} </view>
//2)多个变量
<wxs module="m1">
var mes = "hello world!!!"
var mes2='保尔科技'
module.exports={
mes:mes,
mes2:mes2
};
</wxs>
<view> {{m1.mes}} </view>
<view> {{m1.mes2}} </view>
//3)函数
<wxs module="m1">
var fn=function(){
return 'this is fn'
}
module.exports={
fn:fn
};
</wxs>
<view> {{m1.fn()}} </view>
//4)data中变量
data: {
arr:[10,20,30,40]
}
<wxs module="m1">
var fn=function(arr){
var a=0
for(var i=0;i<arr.length;i++){
a+=arr[i]
}
return a
}
module.exports={
fn:fn
};
</wxs>
<view> {{m1.fn(arr)}} </view>
//5)在其他文件中引入wxs;
//外部wxs中:
var foo='hello 我是mywxs里的foo';
module.exports.foo=foo
//Wxml中:
<wxs src="../logs/mywxs.wxs" module="mywxs"/>
<view>{{mywxs.foo}}</view>
//6)在wxs中引入其他wxs文件:
//otherwxs.wxs中:
var a=10;
var b=20;
module.exports={
a:a,
b:b
}
//Mywxs中:
var other = require("./otherwxs.wxs");
module.exports.foo=other.b
console.log(other.b)
//Wxml中:
<wxs src="../logs/mywxs.wxs" module="mywxs"/>
<view>{{mywxs.foo}}</view>
三、Mpvue
通过vue写微信小程序(仍需要使用微信开发者工具写项目)
(1)初始化:
vue init mpvue/mpvue-quickstart mpvue
(2)安装依赖:
cd mpvue
npm install
(3)运行:
npm run dev
四、apifm-wxapi
1、什么是“apifm-wxapi
”
微信小程序云开发工具包,借此工具包,你将无需投入服务器、无需接口编程、无需开发后台,将传统开发小程序效率提升百倍
可以在小程序中集成 “apifm-wxapi
” 模块,实现快速开发
如果我们使用 “apifm-wxapi” ,那么我只需要做:
购买服务器,用来运行后台及接口程序;购买域名,小程序中需要通过域名来调用服务器的数据;购买 SSL 证书,小程序强制需要 https 的地址,传统无证书不加密的 http 请求微信不支持;后台程序员开发后台程序,这样才能登录后台进行商品管理、订单维护、资金财务管理等等;后台程序员开发小程序可用的 restfull api 接口或者是 websocket 接口;开发的后台及接口程序的安全性、功能性、稳定性测试,bug调试完毕;- UI 设计师设计精美的小程序界面;
- 前端工程师根据 UI 设计稿进行小程序开发、同时对接 api 接口完成最终小程序的开发;
安装wxapi:
(1)在项目中安装package.json :Npm init
(2)安装:npm install apifm-wxapi
(3)构建npm模块:小程序安装的 npm 模块,还不能直接使用,你需要在开发工具: “工具” --> “构建 npm” ,提示构建成功后,才能使用!
(4)小程序调用
js文件头部引入插件:
const WXAPI = require('apifm-wxapi')
WXAPI.init('gooking')
其中’gooking’为api工厂的专属域名
js文件直接调用方法:
WXAPI.banners().then(res => {
if (res.code == 0) {
this.setData({
banners: res.data
})
}
})
在微信小程序中使用async/ await
(1)在项目中添加runtime.js文件
(2)在需要使用async/ await处添加runtime:
const regeneratorRuntime=require('../../utils/runtime')
(3)使用
async initBanner(){
const res1 = await WXAPI.banners({
type: 'index'
})
console.log(res1.data)
}
五、WeUI
平台能力=>WeUI组件库
weui文档
https://wechat-miniprogram.github.io/weui/docs/quickstart.html#如何使用
1、npm安装
npm install weui-miniprogram
2、构建npm
微信开发者工具=>菜单栏=>工具=>构建npm
3、wxss文件中引入
如果路径不对就看自己的weui-miniprogram
目录所在路径修改即可
@import 'weui-miniprogram/weui-wxss/dist/style/weui.wxss';
4、使用
(1)先在.json
文件中,配置引用组件的名字
{
"usingComponents": {
"mp-dialog": "weui-miniprogram/dialog/dialog"
}
}
(2)然后就可以在对应页面的 .wxml
中直接使用该组件
<mp-dialog title="test" show="{{true}}" bindbuttontap="tapDialogButton" buttons="{{buttons}}">
<view>test content</view>
</mp-dialog>
js
配置参数
Page({
data: {
buttons: [
{ text: '取消' },
{ text: '确认' }
]
}
})
注意:
如果文档中没有写的所需组件使用方式:
1、看构建的npm包中有没有该组件文件夹,如果有则直接复制过来使用即可**(class类名要保留)**
2、去浏览器的weui官网看,F12代码审查将
div
标签换成小程序中的view
也可以用