小程序特点:适合简单的、用完即走的,低频的,对性能要求不高的应用。
小程序开发文档:https://developers.weixin.qq.com/miniprogram/dev/index.html?t=18100817
小程序UI:https://weui.io/
小程序开发者工具下载:https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html?t=18101214
第一部分
起步
新建项目-->>建立普通快速启动模版
根目录下小程序入口文件必须要有
页面配置
由 4 个文件组成 x.js(逻辑)、x.json(配置)、x.wxml(框架)、x.wxss(样式)。
创建目录及文件技巧,只要在全局配置文件 app.json 中 “pages” 数组下输入相应的 path("pages/detail/detail"),保存便可以在目录中自动生成对应的目录及文件(detail目录、detail.js、detail.json、detail.wxml、detail.wxss), js、json 文件已初始化好。
//app.json
{
"pages": [
"pages/detail/detail"
]
}
//x.js 文件配置
Page({
})
//x.json 文件配置
{
}
小程序页面数量限制
横向页面可以无限多,纵向页面最多只能 5 级, 层级越简单,小程序越轻便。
小程序标签
view 容器标签类似 html 中的 div。
text 文本标签,包裹的文字可以长按复制,可以嵌套 text 标签,支持转义字符 \n(换行)、\t(空格)多个 \t 只显示一个空格。image 图片标签,默认宽高 300px * 225px。
<text class='user-name'>
H \n ello
<text style='color:#f00'>smile</text>
</text>
<image src="../../images/home.png"></image>
小程序样式
动态样式写在 style 里,静态样式写在 wxss 文件里。
小程序最外层有一个 page 标签包裹着
/*app.wxss*/
.container{
display: flex;
flex-direction: column;
}
小程序自适应单位 rpx(根据屏幕宽度自适应)
- rpx 是以 iPhone6 的物理像素为视觉稿进行设计。
- iPhone6 下 1px = 1rpx = 0.5pt,使用 rpx 小程序会自动在不同的分辨率下进行转换,使用 px 不会。不是所有的单位都适合用 rpx 适情况而定。字体设置不常用 rpx,机型小的话,字体会变小不适合阅读。
- 屏幕尺寸:指的是设备物理尺寸,即对角线的长度;
- pt 逻辑分辨率,与屏幕尺寸有关,可以理解为长度和视觉单位;
- px 物理分辨率,与屏幕尺寸无关,用于描述像素点的多少;
- pt 与 px 的关系:px 个数 = pt 个数 * reader;
第二部分
新建页面
小程序规定 app.json 中的 pages 数组下第一个元素代表你要启动显示的第一个页面。每新建一个页面,要在 pages 数组下注册并添加路径目录。
//app.json
{
"pages":[
"pages/index/index",
"pages/detail/detail"
]
}
swiper 组件
滑块视图容器,swiper-item 仅可放置在 <swiper/> 组件中,宽高自动设置为 100%,image 不会继承父容器的宽高需要设置。
<!--post.wxml-->
<view class="container">
<swiper class='swiper' indicator-dots='true' autoplay='true' circular='true'>
<swiper-item>
<image src="/images/vr.png"></image>
</swiper-item>
<swiper-item>
<image src="/images/wx.png"></image>
</swiper-item>
</swiper>
</view>
indicator-dots 指示点,autoplay 自动播放,circular 衔接滑动。
/*post.wxss*/
.swiper, .swiper image{
width: 100%;
height: 500rpx
}
window
设置小程序的状态栏、导航条、标题、窗口背景色。
//app.json
{
"window":{
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "小程序开发",
"navigationBarTextStyle":"black",
"backgroundColor": "#f6f6f6",
"backgroundTextStyle": "dark"
}
}
navigationBarTextStyle | String | white | 导航栏标题颜色,仅支持 black / white |
navigationStyle | String | default | 导航栏样式,仅支持以下值:default 默认样式。custom 自定义导航栏,只保留右上角胶囊按钮。 |
backgroundColor | HexColor | #ffffff | 窗口的背景色 |
backgroundTextStyle | String | dark | 下拉 loading 的样式,仅支持 dark / light |
构建新闻列表页
<!--post.wxml-->
<view class='post-container'>
<view class='post-author-date'>
<image class='post-author' src='/images/1.png'></image>
<text class='post-date'>Sep 18 2016</text>
</view>
<text class="post-title">菊黄蟹正肥,品尝秋之味</text>
<image class='post-image' src='/images/crab.png'></image>
<text class='post-content'>菊黄蟹正肥,品尝秋之味。徐志摩把,“看初花的荻芦”和“到楼外楼吃蟹”,并列为秋天来杭州不能错过的风雅之事;用林妹妹的话讲是“螯封嫩玉双双满,</text>
<view class='post-like'>
<image class='post-like-image' src='/images/chat.png'></image>
<text class='post-like-font'>112</text>
<image class='post-like-image' src='/images/view.png'></image>
<text class='post-like-font'>112</text>
</view>
</view>
/*post.wxss*/
.post-container{
display: flex;
flex-direction: column;
margin-bottom: 10px;
background-color: #fff;
border-top: 1px solid #ededed;
border-bottom: 1px solid #ededed;
}
.post-author-date{
margin: 10px;
}
.post-author{
width: 60rpx;
height: 60rpx;
margin-right: 10px;
vertical-align: middle;
}
.post-date{
font-size: 26rpx;
vertical-align: middle;
}
.post-title{
font-size: 34rpx;
font-weight: 600;
color: #333;
margin: 0 10px 10px 10px;
}
.post-image{
width: 100%;
height: 340rpx;
}
.post-content{
color: #666;
font-size: 28rpx;
margin: 10px 20rpx;
letter-spacing: 2rpx;
line-height: 40rpx;
}
.post-like{
font-size: 13px;
color: #666;
line-height: 16px;
margin-left: 10px;
margin-bottom: 10px;
}
.post-like-image{
width: 16px;
height: 16px;
margin-right: 8px;
vertical-align: middle;
}
.post-like-font{
vertical-align: middle;
margin-right: 20px;
}
水平距离建议用 rpx,垂直距离建议用 px。
绝对路径( / )从根结点开始查找,相对路径( ../ )从当前文件开始向上查找。
可以在垂直布局(flex弹性)排列中加入水平排列。
js文件结构与Page页面的生命周期
前后端分离的开发方式:前端模拟数据显示预览效果,最后再对接服务器数据。
js 文件:小程序的所有脚本都需要放在 Page({ }) 结构体系里完成。
小程序生命周期函数:onLoad 监听页面加载(页面初始化),onShow 监听页面显示,onReady 监听页面初次渲染完成,onHide 监听页面隐藏,onUnload 监听页面卸载,on 开头的是监听事件。
前端需要写完所有的布局、样式都正常的情况下再去做与服务器对接数据,如果直接做对接数据,这样会分散很多精力。
data 页面初始数据,小程序总会去访问 js 文件中的 data 对象,访问动作总是在 onLoad() 方法【监听页面加载】之后执行。
//post.js
Page({
//页面的初始数据
data: {
},
//生命周期函数--监听页面加载
onLoad: function (options) {
console.log('onLoad')
},
//生命周期函数--监听页面初次渲染完成
onReady: function () {
console.log('onReady')
},
//生命周期函数--监听页面显示
onShow: function () {
console.log('onShow')
},
//生命周期函数--监听页面隐藏
onHide: function () {
console.log('onHide')
},
//生命周期函数--监听页面卸载
onUnload: function () {
console.log('onUnload')
},
//页面相关事件处理函数--监听用户下拉动作
onPullDownRefresh: function () {
console.log('onPullDownRefresh')
},
//页面上拉触底事件的处理函数
onReachBottom: function () {
console.log('onReachBottom')
},
//用户点击右上角分享
onShareAppMessage: function () {
console.log('onShareAppMessage')
}
})
小程序数据绑定this.setData()
- 小程序没有 dom 节点,也不需要获取 dom 节点,可以直接做数据绑定。
- 小程序数据绑定使用双大括号 {{ }},小程序是单向数据绑定,只能通过 js 绑定到 wxml 中。
- 服务器上请求的数据放在 onload 生命周期函数里,this.setData 接收服务器传递过来的变量名,this.setData 相当于把数据写入 data{ } 对象中。
- 绑定的数据放到标签属性里需要加引号 src="{{ }}",绑定的数据放在标签内容里 <text>{{ }}</text>,不需要引号。
<!--post.wxml-->
<view class="container">
<text>{{title}}</text>
<text>{{date}}</text>
<image src='{{post_img}}'></image>
</view>
//post.js
Page({
//页面的初始数据
data: {
},
//生命周期函数--监听页面加载
onLoad: function (options) {
//options 页面跳转所带来的参数
var post_data={
title: '小程序数据绑定',
date: '2018.11.26',
post_img: '/images/1.jpg'
}
this.setData(post_data)
}
})
wx:if 控制标签显示还是隐藏。小程序中布尔值 false 需要加双大括号 {{false}} 表示假,不然小程序会自动解释成 true。
<!--post.wxml-->
<view class='post-container'>
<view class='post-author-date'>
<image class='post-author' wx:if='{{false}}' src='{{img.author_img}}'></image>
<text class='post-date' wx:if='{{img_condition}}'>{{date}}</text>
</view>
<text class="post-title">{{title}}</text>
<image class='post-image' src='{{img.post_img}}'></image>
<text class='post-content'>{{content}}</text>
<view class='post-like'>
<image class='post-like-image' src='/images/chat.png'></image>
<text class='post-like-font'>{{collect_num}}</text>
<image class='post-like-image' src='/images/view.png'></image>
<text class='post-like-font'>{{view_num}}</text>
</view>
</view>
//post.js
Page({
data: {
},
onLoad: function (options) {
//页面初始化 options 为页面跳转所带来的参数
var post_content1 = {
date: 'Sep 18 2016',
title: '正式虾肥蟹壮时',
img: {
author_img: '/images/1.png',
post_img: '/images/crab.png'
},
img_condition: true,
content: '正式虾肥蟹壮时,品尝秋之味',
view_num: '112',
collect_num: '96'
}
this.setData(post_content1);
}
})
使用列表渲染wx:for改写新闻列表
循环放在 block 标签中,block 没有实际作用,block 标签包裹的代码,被视为一个整体。
wx:for='{{post_key}}' wx:for-item='item' wx:for-index='index' 后面两个属性可以省略小程序自带。
<!--post.wxml-->
<block wx:for='{{posts_key}}' wx:for-item='item' wx:for-index='index'>
<view class='post-container'>
<view class='post-author-date'>
<image wx:if='{{false}}' class='post-author' src='{{img.author_img}}'></image>
<text wx:if='{{img_condition}}' class='post-date'>{{date}}</text>
</view>
<text class="post-title">{{title}}</text>
<image class='post-image' src='{{img.post_img}}'></image>
<text class='post-content'>{{content}}</text>
<view class='post-like'>
<image class='post-like-image' src='/images/chat.png'></image>
<text class='post-like-font'>{{collect_num}}</text>
<image class='post-like-image' src='/images/view.png'></image>
<text class='post-like-font'>{{view_num}}</text>
</view>
</view>
</block>
//post.js
Page({
data: {
//posts_key: []
},
onLoad: function (options) {
//页面初始化 options 为页面跳转所带来的参数
var posts_content = [{
date: 'Sep 18 2016',
title: '正式虾肥蟹壮时',
author_img: '/images/1.png',
post_img: '/images/crab.png',
img_condition: true,
content: '正式虾肥蟹壮时,品尝秋之味',
view_num: '112',
collect_num: '96'
}, {
date: 'Nov 25 2016',
title: '比利 林恩的中场故事',
author_img: '/images/12.png',
post_img: '/images/bl.png',
img_condition: true,
content: '李安是一位绝不会重复自己的导演',
view_num: '112',
collect_num: '96'
}]
this.setData({
posts_key: posts_content
});
}
})
小程序的事件机制(冒泡与非冒泡)
事件前面需要加bind(冒泡)、 catch(捕获),例:bindtap,tap 手指触摸后马上离开。
<!--welcome.wxml-->
<view class="user-container" bindtap='onTap'>
<text class='user-info'>开启小程序之旅</text>
</view>
//welcome.js
onTap: function(){
wx.navigateTo({
url: '../post/post',
})
// wx.redirectTo({
// url: '../post/post',
// })
},
catch、bind 的区别是 catch 可以阻止冒泡事件,即点击子元素触发事件的同时并不触发父元素的事件。
<!--welcome.wxml-->
<view class="user-container" bindtap='onTap'>
<text class='user-info' catchtap='onSubTap'>开启小程序之旅</text>
</view>
//welcome.js
Page({
onTap: function(){
console.log('onTap bind')
},
onSubTap: function(){
console.log('onSubTap catch')
}
})
API 路由配置:
- wx.navigateTo() 保留当前页面,跳转到应用内的某个页面,带返回按钮,触发的是 onHide() 生命周期函数,不能跳转到 tabbar(标签栏) 页面。使用 wx.navigateBack 可以返回到原页面。==》父级跳到子级,限制5级跳转。
- wx.redirectTo() 关闭当前页面,跳转到应用内的某个页面,不带返回按钮,触发的是 onUnload() 生命周期函数,不允许跳转到 tabbar 页面。==》平级跳转。
- wx.reLaunch() 关闭所有页面,打开到应用内的某个页面,可以跳转到 tabbar 页面。
- wx.switchTab() 跳转到 tabBar 页面,关闭其他所有非 tabBar 页面。
- wx.navigateBack() 关闭当前页面,返回上一页面或多级页面。可通过 getCurrentPages() 获取当前的页面栈,决定需要返回几层。
wx.navigateBack() 参数:
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
delta | number | 是 | 返回的页面数,如果 delta 大于现有页面数,则返回到首页。 | |
success | function | 否 | 接口调用成功的回调函数 | |
fail | function | 否 | 接口调用失败的回调函数 | |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
示例代码:
// 注意:调用 navigateTo 跳转时,调用该方法的页面会被加入堆栈,而 redirectTo 方法则不会。
// 此处是A页面
wx.navigateTo({
url: 'B?id=1'
})
// 此处是B页面
wx.navigateTo({
url: 'C?id=1'
})
// 在C页面内 navigateBack,将返回A页面
wx.navigateBack({
delta: 2
})
url 路径后可带参数。路径与参数之间用 ? 分隔,参数键与值用 = 相连,不同参数用 & 分隔; 'path?key=value&key2=value2'。
参考资料来自慕课网:微信小程序入门与实战。