一、创建项目
1、准备工作
微信公众平台注册开发者账号:https://mp.weixin.qq.com/
下载小程序开发工具:
https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html
2、认识项目目录
pages目录:用于存放所有的页面。
utils目录:用于存放工具类文件。
app.js:是入口文件,程序在运行时,首先要执行该文件。
app.json:是全局配置文件,用于配置小程序的信息(它里面配置的是全局信息)。
app.wxss:是全局样式文件。全局样式文件里面定义的选择器,在所有的页面中生效。
project.config.json:是项目配置文件。
sitemap.json:是SEO配置文件,方便用户搜索到该小程序。
[if !supportLists]2、[endif]app.json
(1)pages配置项
pages里面注册的是视图。用于指定小程序由哪些页面组成,每一项都对应一个页面的路径(含文件名)信息。
"pages":[
"pages/index/index"
]
(2)window配置项
window 是全局窗口配置。
backgroundTextStyle 设置文本样式(下拉loading的样式),仅支持 dark / light。
navigationBarBackgroundColor 设置导航栏背景。
navigationBarTitleText 设置导航栏文本。
navigationBarTextStyle 设置导航栏标题颜色,仅支持 black / white。
"window":{
"backgroundTextStyle":"light",
"navigationBarBackgroundColor": "#369",
"navigationBarTitleText": "KW43-APP",
"navigationBarTextStyle":"white"
}
(3)style
style 设置样式级别,默认是v2。
"style": "v2"
(4)sitemapLocation
sitemapLocation 指明sitemap.json 的位置;默认为 'sitemap.json' 即在 app.json 同级目录下名字的 sitemap.json 文件。
"sitemapLocation": "sitemap.json"
[if !supportLists]3、[endif]页面组成
每一个页面由四个文件组成:xxx.wxml文件、xxx.wxss文件、 xxx.js文件和xxx.json文件。
(1)xxx.wxml文件
xxx.wxml文件,就相当于一个html文件。在wxml文件中,不能写传统的html标签,只能写微信提供的组件。
① view组件
相当于div标签。
② text组件
相当于span标签。
③ swiper
swiper是滑块视图容器,它里面只能放swiper-item组件。
swiper组件的常用属性:
circular是衔接滑动
autoplay是自动切换
interval是自动切换时间间隔
indicator-dots是否显示面板指示点
indicator-color指示点颜色
indicator-active-color当前选中的指示点颜色
<swiper class="swiper" circular autoplay interval="3000" indicator-dots indicator-color='#eee' indicator-active-color='#369'>
</swiper>
④ image
image是图片组件,最好全部采用网络图片,因为小程序的总体积不允许超过2MB。
(2)xxx.wxss文件
xxx.wxss文件,就相当于一个css文件。在wxss文件中,最好不要写标签选择器和id选择器,统一写类选择器。
为了让小程序里面的内容在各种设备上能够自适应显示,微信推出了响应式单位:rpx。在iphone6中,2rpx=1px。
width: 60rpx; /* 相当于width: 30px; */
(3)xxx.js文件
xxx.js文件,是交互文件(核心文件)。
Page()函数,返回页面对象,该函数需要传一个配置参数,这个配置参数是一个对象。在这个配置对象中,定义当前页面的所有内容。
① data
定义页面的数据。
Page({
data: {
name: "热门歌曲",
songs: [{id: 1001}, {id: 1002}]
}
})
② 自定义函数
开发者可以添加任意的函数或数据到Object 参数中,在页面的函数中用this可以访问。
Page({
// 定义函数
delSong() {
this.data.songs.splice(0, 1)
this.setData({
songs: this.data.songs
})
}
})
(4)xxx.json文件
xxx.json文件,是页面的配置文件(它里面配置的是当前页面信息)。
5、插值表达式 {{}}
WXML 中的动态数据均来自对应 Page 的 data。
(1)获取data中数据
通过插值表达式{{}},可以显示js里面定义的data里面的数据。
<text>歌曲分类:{{name}}</text>
(2)组件属性(需要在双引号之内)
<view id="item-{{id}}"> </view>
(3)运算
可以在{{}} 内进行简单的运算。
① 三元运算
<view class="item {{index%2===0 ? 'bg' : ''}}"> </view>
② 逻辑判断
<view wx:if="{{length > 5}}"> </view>
6、bindtap
bindtap是触屏事件,其实就是相当于网页中的点击事件。
<view class="btn" bindtap="delSong">删除</view>
7、data-xxx 自定义属性
小程序中bindtap绑定方法时不能传参数。所以组件通过data-xxx传递数据。
<view class="btn" data-index="{{index}}" bindtap="del1">删除</view>
注意:自定义属性的命名用驼峰或者大写命名,小程序内部会自动转成小写。
del(e){
//解构出自定义的index属性
let {currentTarget:{dataset:{index}}} = e
}
8、setData()方法
setData()方法,更新页面中数据。页面数据更新后,调用setData()方法重新渲染到页面。
this.setData({
typeId:typeid,
name:typename
})
二、列表渲染
1、wx:for
wx:for指令用于循环数组数据,生成组件。
循环出来的每一项通过item返回,每一项对应的索引,通过index返回。
<view wx:for="{{songs}}" wx:key="index" class="items">
<text>{{index}}--{{item.id}}--{{item.name}}</text>
</view>
2、wx:key
wx:key="",设置每一项唯一的标识。循环列表时,添加wx:key的好处是,将来列表发生变化时重新渲染列表的损耗为更低。
三、条件渲染
条件渲染可以使用wx:if或hidden。
一般来说,wx:if 有更高的切换消耗而 hidden 有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用 hidden 更好,如果在运行时条件不大可能改变则 wx:if 较好。
1、wx:if
wx:if用于条件渲染:条件为真生成里面的内容,条件为假不会生成里面的内容。(每次重新生成内容)
也可以用wx:elif 和 wx:else 来添加一个 else 块。
<view wx:if="{{typeID == 1}}"> 1 </view>
<view wx:elif="{{typeID == 2}}"> 2 </view>
<view wx:else> 3 </view>
2、hidden
hidden用于条件渲染:条件为真隐藏里面的内容,条件为假显示里面的内容。(每次切换样式)
<view hidden="{{typeID!= 2}}"> 1 </view>
四、tabBar&页面跳转
1、tabBar
在app.json文件中添加tabBar节点。tabBar是小程序客户端底部或顶部tab栏的实现。
(1)tabBar相关属性
color:tab上的文字默认颜色,仅支持十六进制颜色。
selectedColor:tab上的文字选中时的颜色,仅支持十六进制颜色。
backgroundColor:tab的背景色,仅支持十六进制颜色。
borderStyle:tabbar上边框的颜色, 仅支持 black / white。
position:tabBar的位置,默认值是: bottom,仅支持 bottom / top。当 position 为 top 时,不显示 icon。
custom:自定义tabBar。
"tabBar": {
"color": "#000000",
"selectedColor": "#336699",
"backgroundColor": "#ffffff",
"borderStyle": "black",
"position": "bottom"
}
(2)list
list:tab的列表。
list 接受一个数组,只能配置最少 2 个、最多 5 个 tab。
pagePath:页面路径,必须在pages 中先定义。
text:tab 上按钮文字。
iconPath:图片路径,icon 大小限制为 40kb,建议尺寸为 81px * 81px,不支持网络图片。selectedIconPath:选中时的图片路径,icon 大小限制为 40kb,建议尺寸为 81px * 81px,不支持网络图片。
"list": [
{
"text": "首页",
"pagePath": "pages/index/index",
"iconPath": "assets/icon/home.png",
"selectedIconPath": "assets/icon/home2.png"
},
{
"text": "列表",
"pagePath": "pages/list/list",
"iconPath": "assets/icon/list.png",
"selectedIconPath": "assets/icon/list2.png"
}
]
2、页面跳转
(1)跳转普通页面
方法① navigator组件
<!-- 跳转到普通页,可以通过返回按钮返回 -->
<navigator url="../detail/detail">到详情页</navigator>
方法② navigateTo()方法
navigateTo()方法,用于跳转普通页面。
<view bindtap="gotoDetail">到详情页</view>
gotoDetail(){
//使用全局api跳转,navigateTo()方法,用于跳转普通页面
wx.navigateTo({
url: '../detail/detail',
})
}
(2)跳转tabBar页面
方法① navigator组件
如果要使用navigator组件跳转tabBar页面,需要设置open-type="switchTab"。
<!-- 跳转到tabBar页面,不可以通过返回按钮返回。因为跳转到指定的tabBar页面后,会关闭其他所有页面 -->
<navigator url="../list/list" open-type="switchTab">到列表页</navigator>
方法② switchTab()方法
switchTab()方法,用于跳转tabBar页面。
<view bindtap="gotoList">到列表页</view>
gotoList(){
wx.switchTab({
url: '../list/list',
})
}
五、确认框和消息框
1、wx.showModal() 确认框
title:提示的标题
content:提示的内容
success:接口调用成功的回调函数。回调函数中的confirm属性返回true,表示点击的是确定按钮,否则是取消按钮。
wx.showModal({
content:'是否确定删除',
success:({confirm})=>{
//confirm返回true,表示点击的是确定按钮,否则是取消按钮
if(confirm){
}
})
2、wx.showToast() 显示消息提示框
title:提示的内容
icon:图标
duration:消息提示框的显示时间
mask:是否显示透明蒙层,防止触摸穿透
wx.showToast({
title: '删除成功',
icon:"success",
duration:1500,
mask:true
})
六、封装方法
模块化语法有两种:① commonjs规范,② es6规范。
nodejs环境采用的就是commonjs规范。采用exports 或 module.exports 导出成员,采用require() 导入成员。
微信小程序支持commonjs规范,同时还支持官方的ES6规范。ES6规范采用export 导出成员,采用import 导入成员。
[if !supportLists]1、[endif]封装方法并导出
将封装的方法放到util目录下的js文件中。可以新建js文件,也可以写在直接util.js文件中。
(1)确认框方法
// 定义确认框方法,并导出
export let $confirm = (content)=>{
return new Promise((resolve)=>{
wx.showModal({
content,
success:({confirm})=>{
if(confirm){
resolve()
}
}
})
})
}
(2)消息框方法
// 定义消息框方法,并导出
export let $msg = (title,icon='success',duration=1500)=>{
wx.showToast({
title,
icon,
duration,
mask:true
})
}
(3)获取事件参数的方法
export let $key = (e)=>{
return e.currentTarget.dataset
}
[if !supportLists]2、[endif]导入方法
import是ES6的导入语句。
// 导入msg模块中的指定成员
import {$msg,$confirm} from '../../utils/msg'
[if !supportLists]3、[endif]将方法注册给全局对象wx
wx对象是微信小程序的全局对象,在任何地方都可以使用。
[if !supportLists](1)[endif]注册语句
wx.$msg = $msg
wx.$confirm = $confirm
[if !supportLists](2)[endif]在app.js入口文件中导入
注意:注册给wx对象的方法,需要在app.js文件中导入,才可使用。
// 导入初始化文件
import './utils/index'
[if !supportLists](3)[endif]调用方法
wx.方法名(参数)
wx.$msg('删除成功')
七、scroll-view
可滚动视图区域。使用竖向滚动时,需要给scroll-view一个固定高度,通过 WXSS 设置 height。组件属性的长度单位默认为px,2.4.0起支持传入单位(rpx/px)。
scroll-x:允许横向滚动。
scroll-y:允许纵向滚动。
<scroll-view class="left" scroll-y> </scroll-view>
八、wx对象发送ajax请求
1、wx.request() 发送请求
注意:小程序实际使用中,请求的接口必须都是已经配置过的接口。开发阶段,可以直接设置“不校验合法域名”,暂不配置。
wx.request({
// 请求接口地址
url: 'https://www.bingjs.com:8002/Section/GetSections',
// 请求参数
data:{},
// 请求方式GET/POST
method:"GET",
// 请求成功后的回调
success:({data})=>{
resolve(data)
},
// 请求完成后的回调
complete:()=>{
console.log('请求完成');
}
})
2、封装ajax请求方法
(1)定义请求方法
export let $request = (url,data={},method='GET')=>{
return new Promise((resolve)=>{
wx.request({
url,
data,
method,
success:({data})=>{
resolve(data)
},
})
})
}
(2)定义get请求方法
export let $get = (url,data={})=>{
return $request(url,data,'GET')
}
(3)定义post请求方法
export let $post = (url,data={})=>{
return $request(url,data,'POST')
}
九、格式化时间
1、在后台对数据里的时间戳进行处理
let data= await wx.$get('Subject/GetSubjects',{section_id:id})
data = data.map(r=>{
return {
Title: r.Title,
Section: r.Section,
Createtime: wx.$formatTime(new Date(parseInt(r.Createtime)))
}
})
2、WXS
WXS(WeiXin Script)是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构。
在wxml页面中,只能在插值{{ }}中写简单的js表达式,而不能调用方法。wxs就是为了能在页面中使用js而存在的。
(1)语法
① 变量必须使用var声明,不支持const或者let。
② 不支持箭头函数。
③ 不可以使用模板字符串,字符串连接用+ 。
④ 每一个 .wxs 文件和 <wxs> 标签都是一个单独的模块。每个模块都有自己独立的作用域。
通过module.exports导出内部的私有变量与函数。
⑤ <wxs> 标签中,module属性值定义标签的模块名;src属性值引入.wxs文件的相对路径。
⑥ 生成date对象使用 getDate(),返回一个当前时间的对象。不使用new Date()。
(2)编写在wxml文件中的 标签内
<wxs module="tools">
var formatTime = function(date) {
date = getDate(parseInt(date))
var year = date.getFullYear()
var month = date.getMonth() + 1
var day = date.getDate()
var hour = date.getHours()
var minute = date.getMinutes()
var second = date.getSeconds()
return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}
var formatNumber =function(n) {
n = n.toString()
return n[1] ? n : '0' + n
}
module.exports = {
formatTime:formatTime
}
</wxs>
<!-- 在模板中,对时间数据进行处理 -->
<view>{{tools.formatTime(item.Createtime)}}</view>
(3)编写在wxs文件中,再导入wxml文件
<!-- 导入wxs文件 -->
<wxs module="tools" src="../../wxs/filter.wxs"></wxs>
<!-- 在模板中,对时间数据进行处理 -->
<view>{{tools.formatTime(item.Createtime)}}</view>
十、生命周期函数
1、onLoad 监听页面加载
onLoad函数对页面状态数据的初始化,是生命周期回调—监听页面加载。一 个页面只会调用一次。onLoad函数的参数可以接收打开当前页面所调用的 query参数。
当前页面跳转detail页面后,调用query参数id。
<navigator url="../detail/detail?id={{item.Id}}" class="item" wx:for="{{subjects}}" wx:key="index">
</navigator>
detail页面中onLoad函数可以获取传递的query参数id。
onLoad: function (options) {
//获取题目的id
let {id} = options
}
2、onReachBottom 上拉触底
onReachBottom:function(){
this.data.pageIndex++
this.getSubjects()
}
[if !supportLists]1、[endif]onPullDownRefresh 下拉刷新
下拉刷新默认是关闭状态,所以需要先在.json文件中设置允许下拉刷新。
enablePullDownRefresh设置是否开启当前页面下拉刷新。
backgroundColor设置窗口的背景色。
{
"enablePullDownRefresh": true,
"backgroundColor": "#d1c2d3"
}
下拉刷新动效有默认时间。如果想改变默认的下拉时间,可以用定时器。
wx.stopPullDownRefresh()设置刷新完成后停止下拉刷新动效。
onPullDownRefresh:function(){
setTimeout(() => {
wx.stopPullDownRefresh()
}, 1000);
}
十一、简易双向绑定
1、普通属性绑定
在WXML 中,普通的属性的绑定是单向的。如果用户修改了输入框里的值,不会同时改变 this.data.value。
<input class="txt" value="{{title}}" />
2、简易双向绑定
如果需要在用户输入的同时改变this.data.value ,需要借助简易双向绑定机制。
通过model:value的方式,将表单里面的数据跟js里面的数据进行了双向绑定。
双向绑定指的是:一处被修改,另一处也一起修改。
<input class="txt" model:value="{{value}}" />
3、双向绑定的表达式限制
只能是一个单一字段的绑定;目前,尚不能data 路径。
以下写法都是错误的:
<input model:value="值为{{value}}" />
<input model:value="{{ a + b }}" />
<input model:value="{{ a.b }}" />
十二、表单组件
1、picker 选择器组件
range:指定一个数组(指定一份展示的数据)。
range-key:如果range数组是一个对象数组,需要添加range-key属性,指定选择器中显示的内容(从对象身上指定一个属性)。
bindchange:value 改变时触发 change 事件,event.detail = {value}。
<picker class="txt" bindchange="bindPickerChange" range-key="Name" range="{{sections}}">
<view>
<!-- 根据选择器选中的索引,显示对应的名称 -->
{{sections[sectionsActiveIndex].Name}}
</view>
</picker>
通过e.detail.value获取当前列表value的索引。
bindPickerChange: function(e) {
console.log(e.detail.value) //获取下标
}
2、input 输入框
placeholder:输入框为空时占位符。
<input value="" placeholder="请输入搜索关键字" />
3、textarea 多行文本框
maxlength:最大输入长度。设置为 -1 的时候不限制最大长度。
<textarea maxlength="-1" value="" />
十三、js数据更新方法
(1)直接赋值
该方法只更新js中的数据,不会重新渲染到页面。
this.data.section_id = this.data.sections[index].Id
(2)setData()方法
该方法更新数据后,重新渲染页面。
this.setData({
activeIndex: index
})