一直从事安卓开发,前不久公司突然让我研究一下微信小程序。微信小程序的需求现在越来越多了,各种大小公司现在一开口就是来给我做个小程序,微信小程序以其“即用即走”的超便利特性受到越来越多用户的青睐,毕竟有些时候你并不想花时间或者流量去下载一个app,小程序能够以一种极轻的方式展现在用户面前,最终完成一定的业务流程。而且现在的小程序功能及UI已经不比原生的应用差太多了。我觉得小程序应该是以后的发展方向吧(这几年的发展已经印证了这一点)好了废话不多说,马上开始。
微信小程序的基本结构
先来下载开发者工具 新建项目,选择一个空的目录作为项目路径,没有appid的选择使用测试号
项目建立之后的项目结构如下
App全局文件
1、app.js 是小程序的逻辑,一个小程序只能在这里注册一个App
App({//生命周期
onLaunch: function() { },//监听初始化
onShow: function() { },//监听显示(进入前台)
onHide: function() { },//监听隐藏(进入后台:按home离开微信)
onError: function(msg) { },//监听错误
//自定义的全局方法和全局变量
globalFun:function(){},
globalData: 'I am global data'
})
复制代码
2、app.json 是当前小程序的全局配置,包括了小程序的所有页面路径、界面表现、网络超时时间、底部 tab 等.page.json对于page进行单独的页面设置可覆盖app.json的属性值
{
"pages":[
"pages/index/index",
"pages/logs/logs"
],
"window":{
"backgroundTextStyle":"light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "WeChat",
"navigationBarTextStyle":"black"
}
}
复制代码
3、app.wxss 是小程序的全局样式,wxss对应到web上的css
.container {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
padding: 200rpx 0;
box-sizing: border-box;
}
复制代码
Page包含的文件
pages是小程序所包含的页面,在pages文件夹下面新建空目录,右键选择生成页面即可生成页面所需要的文件,即page.js、page.json、page.wxss、page.wxml,page.json和page.wxss为非必须
1、page.js 一个page一个Page入口,用于管理页面的生命周期
Page({
data: {text: "This is page data."},//页面数据,用来维护视图,json格式
onLoad: function(options) { },//监听加载
onReady: function() { },//监听初次渲染完成
onShow: function() { },//监听显示
onHide: function() { },//监听隐藏
onUnload: function() { },//监听卸载
onPullDownRefresh: function() { },//监听下拉
onReachBottom: function() { },//监听上拉触底
onShareAppMessage: function () { },//监听右上角分享
//如下为自定义的事件处理函数(视图中绑定的)
viewTap: function() {//setData设置data值,同时将更新视图
this.setData({text: 'Set some data for updating view.'})
}
})
复制代码
2、page.wxml 为page的view 用于数据的展示,view对应于我们html的div,text则对应于span,自动生成的index.wxml如下,实现一个点击登录的功能
<view class="container">
<view class="userinfo">
<button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 获取头像昵称 </button>
<block wx:else>
<image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
<text class="userinfo-nickname">{{userInfo.nickName}}</text>
</block>
</view>
<view class="usermotto">
<text class="user-motto">{{motto}}</text>
</view>
</view>
复制代码
3、数据的绑定,结合官方示例,写一个简单的page demo
page.wxml
<!-- 简单绑定 -->
<view> {{ message }} </view>
<!-- 组件属性 -->
<view id="item-{{id}}">{{id}}</view>
<!-- 控制属性 -->
<view wx:if="{{condition}}"> condition</view>
<!--关键字(需要在双引号之内)
true:boolean 类型的 true,代表真值。
false: boolean 类型的 false,代表假值。-->
<checkbox checked="{{false}}"> </checkbox>
<!-- 字符串运算 -->
<view>{{"hello" + name}}</view>
<!-- 数据路径运算 -->
<view>{{object.key}} {{array[0]}}</view>
<!-- 循环遍历 -->
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
{{idx}}: {{itemName.message}}
</view>
<!-- 模板 -->
<template name="msgItem">
<view>
<text> {{index}}: {{msg}} </text>
<text> Time: {{time}} </text>
</view>
</template>
<template is="msgItem" data="{{...item}}"/>
<!-- 点击事件 -->
<view id="tapTest" data-hi="WeChat" bindtap="tapName"> Click me! </view>
复制代码
page.js
Page({
data: {
message: 'Hello MINA!',
id: 0,
condition: true,
name: 'MINA',
object: {
key: 'Hello '
},
array: ['MINA'],
array: [{
message: 'foo',
}, {
message: 'bar'
}],
item: {
index: 0,
msg: 'this is a template',
time: '2016-09-15'
}
},
tapName: function (event) {
console.log(event)
}
})
复制代码
豆瓣Top250
一直都喜欢用豆瓣电影的接口来做一些新技术的学习,哈哈
可以看看我之前的这篇文章,Python3 爬取豆瓣电影Top250
豆瓣接口对于微信小程序的访问做了限制,用了一个其他的接口,返回的数据是一致的 douban.uieee.com/v2/movie/to…
此外在开发时ide记得勾选不校验域名,正式上线以后要把域名配到合法域名当中去
下面直接上代码
app.json
{
"pages": [
"pages/list/list",
"pages/detail/detail"
],
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#072",
"navigationBarTitleText": "豆瓣电影",
"navigationBarTextStyle": "light"
}
}
复制代码
list.wxml
<!--pages/list/list.wxml-->
<wxs module="filters" src="./list.wxs"></wxs>
<view wx:for="{{movies}}" wx:key="{{item.id}}" data-index="{{index}}" class ="movie_item" bindtap="goDetail">
<image class="image" src="{{item.images.small}}"></image>
<view class="movie_info">
<text class="title">{{item.title}}</text>
<view class="star">
<text class="{{filters.getRating(item.rating.average)}}"></text>
<text class="rating_num">{{filters.toFix(item.rating.average)}}</text>
</view>
</view>
</view>
复制代码
list.js
var start = 0;
Page({
start: 0,
/**
* 页面的初始数据
*/
data: {
movies: []
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
var that = this;
this.loadMore(that);
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
start = 0;
var that = this;
this.loadMore(that);
wx.stopPullDownRefresh();
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
var that = this;
this.loadMore(that);
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
},
loadMore:function(that){
that.getMovie(function (d) {//回调函数,根据数据设置页面data,更新到视图
wx.hideToast();//隐藏加载框
var list = that.data.movies;
for(var i=0;i<d.length;i++){
list.push(d[i]);
}
that.setData({ movies: list })//更新数据,视图将同步更新
})
},
getMovie:function(fn) {
wx.showToast({ title: '加载中', icon: 'loading', duration: 10000 })
wx.request({//请求服务器,类似ajax
url: 'https://douban.uieee.com/v2/movie/top250?start='+start,
header: { 'content-type': 'json' },
success: function (res) {
start=start+20;
console.log(res)
fn(res.data.subjects) }//成功后将数据传给回调函数执行
})
},
goDetail:function(e) {
var that = this
//拿到点击的index下标
var index = e.currentTarget.dataset.index
var movie = JSON.stringify(that.data.movies[index])
wx.navigateTo({
url: '../detail/detail?movie='+movie,
})
}
})
复制代码
list.wxss
.movie_item {
margin: 8px;
border-radius: 5px;
background-color: #fff;
box-shadow: 1px 1px 1px #cccccc;
position: relative;
display: block;
padding: 8px;
overflow: hidden;
box-sizing: border-box;
}
.image {
width: 64px;
height: 100px;
margin-right: 15px;
background-color: #eeeeee;
float: left;
}
.movie_info {
float: left
}
.title {
font: 12px Arial, Helvetica, sans-serif;
line-height: 150%;
color: #669;
}
.rating10-t, .rating15-t, .rating20-t, .rating25-t, .rating30-t, .rating35-t, .rating40-t, .rating45-t, .rating50-t, .rating-t{
display: inline-block;
zoom: 1;
background: url(https://img3.doubanio.com/f/shire/b8f4c3672ef81106701071831e22422a745d3b74/pics/rating_icons/ic_rating_s.png) no-repeat;
width: 55px;
height: 11px;
margin: 0 3px 0 0;
overflow: hidden;
}
.rating50-t {
background-position: 0 0px;
}
.rating45-t {
background-position: 0 -11px;
}
.rating40-t{
background-position: 0 -22px;
}
.rating_num {
color: #e09015;
padding: 0 5px 0 0;
font-size: 12px;
}
复制代码
list.wxs
var filters = {
getRating:function(value){
return "rating"+Math.round(value)*5+"-t";
},
toFix: function (value) {
return value.toFixed(1)//此处2为保留两位小数
}
}
module.exports = {
getRating: filters.getRating,
toFix: filters.toFix
}
复制代码
讲几个注意点
1、在页面的js里面修改数据
setData({ movies: list })
复制代码
2、在显示豆瓣评分星级的时候不同分数电影的星标的class是不一样的,我们需要根据分数得到class,计算的方法写在wxs文件中 在wxml这样引入方法
<text class="{{filters.getRating(item.rating.average)}}"></text>
复制代码
3、页面的跳转并传递数据可以用query的方式
var movie = JSON.stringify(that.data.movies[index])
wx.navigateTo({
url: '../detail/detail?movie='+movie,
})
复制代码
在下个页面的onload方法里面可以将数据提取出来
onLoad: function (options) {
var that = this
var movie = JSON.parse(options.movie)
console.log(movie.images.small)
that.setData({
movie: movie
})
},
复制代码
效果图如下