0%

微信小程序——开发入门

这个是微信小程序的入门环节。

配置好小程序的开发后


目录规范


utils : 工具类的代码
pages: 页面相关的代码
components: 组建相关的代码
thirdparty: 第三方库
resources: 小程序的资源

小程序的文件类型


.wxml 结构
.wxss 表现
.js 行为
.json 配置


.wxml


用 wxml 获取 js 中的数据,其格式是有要求的,便是,wxml中的动态数据都是来自页面js的Page的data对象,数据绑定是用一个Mustache语法,就是变量名加双括号的语法,也可以绑定属性

.js 中的数据书写

Page({
    data:{
        theName:'JACK'
    }
})

需要注意的是所有的组件和属性要为小写

运算符绑定:

属性:

将 html 的各种标签,比如

<div>、<p> 。。。 

全部变成一个标签

<view>

语法

wx:if
wx:for
{{}}
    不主张用js控制页面的逻辑,而是用 wxml 控制

.wxss


具备CSS的大部分属性

新增尺寸单位

有全局样式和局部样式


.json


工具配置 project.config.json
项目配置 app.json
页面配置 <page name>.json

小程序的入口,配置,样式


全局入口 app.js
全局配置 app.json
全局样式 app.wxss

小程序的配置


全局配置 app.json

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"pages": [
"pages/index/index",
"pages/logs/logs"
],
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "WeChat",
"navigationBarTextStyle": "black"
},
"sitemapLocation": "sitemap.json"
}

pages 配置

保存每一个路径,并且,第一个路径是小程序的首页,千万不要弄错了

window 配置

文字类型、导航条背景颜色、导航条的文字、导航条的背景颜色等

tabBar 配置

这个是只小程序下面有多个页面可以切换,当你输入 tabBar 的时候,它们会自动补全

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
"pages": [
"pages/index/index",
"pages/logs/logs"
],
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "WeChat",
"navigationBarTextStyle": "black"
},
"sitemapLocation": "sitemap.json",
"tabBar": {
"list": [{
"pagePath": "pages/index/index",
"text": "首页",
"iconPath": "",
"selectedIconPath": ""
},
{
"pagePath": "pages/logs/logs",
"text": "日志",
"iconPath": "",
"selectedIconPath": ""
}
]
}
}

页面配置 .json

页面配置只能配置全局配置中的window配置项内容

如果和全局配置冲突,会以页面配置为主

有一个比较特殊的配置项,是是否开启下拉刷新

以 index.json 为例

1
2
3
{
"enablePullDownRefresh": true
}

小程序的逻辑层


小程序的逻辑层也就是 .js 文件

小程序注册逻辑

集中在 app.js 里面

globalData

小程序的全局数据

userInfo 用来保存昵称
onLaunch 生命周期回调函数,是小程序刚打开的时候,自动执行的

app函数是注册全局唯一的小程序,并且只能调用一次,接受一个对象作为函数参数

使用 globalData

微信小程序在JavaScript文件中声明的变量和函数只在该文件中有效;不同的文件中可以声明相同名字的变量和函数,不会互相影响。如果希望在各个页面之间共同使用某些信息,并且可以对共享数据进行修改设置,以便于其他页面根据数据变化进行对应的调整,最好使用全局数据globalData。

globalData在app.js文件中app()全局应用实例中:

// app.js
App({
  globalData: 1
})

由于它具有共享属性,对于它的设置和修改,需要分两方面来说明。

第一,在app.js文件中,怎样设置和修改。设置其实跟在其他js文件中设置data值是一样的:

//app.js
App({
    globalData: {
        name: '张三',
        age: 18
    }
})

你可以根据自己的需求,设置任何数据。在app.js中读取globalData,使用this就可以了:

//app.js
App({
    globalData: {
        name: '张三',
        age: 18
    },
    onLoad: function(){
        console.log(this.globalData.name);
    }
})

同样的,如果我们需要在app.js中修改globalData,只需要给对应的变量重新赋值就可以了:

//app.js
App({
    globalData: {
        name: '张三',
        age: 18
    },
    onLoad: function(){
        this.globalData.name = '李四'
    }
})

第二,在其他页面读取以及修改globalData。不论是读取还是修改,首先需要在应用的页面js文件中,引用app()实例,所以在js文件中,第一句要写上这句:

var app = getApp();

然后,我们来看怎么获取globalData:

//index.js
var app = getApp();
Page({
    onLoad: function() {
        console.log(app.globalData.name);
    }
})

下面看下在其他页面怎么设置或者修改globalData。这里需要用到全局函数 getApp():

//index.js
var app = getApp();
Page({
    onLoad: function() {
        getApp().globalData.name = "王二麻子";
     getApp().globalData.favorite = "集邮";
    }
})

这样,就可以在index.js文件中,重新设置或者修改globalData的数据了。上面的例子,我们修改了globalData的name值,并且添加了一个集邮的爱好的属性。

页面注册逻辑

page函数

注册一个页面

接受一个对象作为函数参数

页面数据

data属性
    data:{
        messgae:"hello"
    }
    访问:this.data.message
    修改:this.setData({})
全局数据
    使用APP函数,可以注册一个全局唯一的数据
    获取全局唯一的APP实例
        const app = getApp()
        var data = app.globalData

页面生命周期

在页面周期里面,主要参与有两个线程,一个是 view thread,另一个是 appservice thread.

其中 view 可以看作视图线程,appservice 可以看作逻辑线程。

当页面启动得时候,这两个线程也会同时启动。

首先是逻辑线程,会依次调用 onLoad、onShow,然后进入等待状态(waiting notify),等待视图线程完成初始化。

当视图线程完成初始化,就会通知(Notify)逻辑线程,并且拿到初始化数据(send initial data),接着便是第一次预渲染(first render)

在第一次渲染结束后,视图线程就会进入 ready 状态,并且通知(notify)逻辑线程,告诉它:我已经准备好了。

这个时候逻辑线程就会进入 onReady 生命周期函数,并且进入 active 状态。

当,视图线程进入 ready 状态,逻辑线程进入 active 状态,我们就可以说,这个页面已经完成初始化了。

在逻辑层进入 active 的状态后,就会不断地监听数据的变化。

当数据发生变化的时候,它会把新的数据发给视图线程,视图线程,拿到新的数据,会做出相应,渲染新的页面给用户。

如果说,在某一个时刻,页面被切换到后台了,那么逻辑线程就会进入 onHide 生命周期函数。

如果说,切换到后台的页面,被重新切换回来,那么就会触发 onShow 生命周期函数。

最后,用户把小程序退出的时候,逻辑线程又会触发 onUnload 生命周期函数。

生命周期回调函数


小程序的视图层


视图层代码的后缀是 .wxml 文件

数据绑定

语法: {{}}

在小程序的逻辑层里面有这样的代码

1
2
3
4
5
Page({
data:{
message:"hello Mima"
}
})

在视图层我们直接

<view> {{message}} </view>

上面的就能显示了。

列表渲染

语法 :wx:for

在逻辑层中

1
2
3
4
5
6
7
8
9
Page({
data:{
array:[{
message:'foo',
},{
message:'bar'
}]
}
})
<view wx:for ="{{array}}">
    {{index}}:{{item.message}}
</view>
    index 是微信约定俗称的,就是第几个的意思,微信会自动排列
    item 也是微信约定俗成,在 array 里面的元素,都是 item
1
2
3
<view wx:for="{{array}}">
NO.{{index}} item,message:{{item.message}}
</view>

就会出现

NO1 item,message:foo
NO2 item,message:bar

条件渲染

语法:wx:if 、 wx:elif 、 wx:else

<view wx:if="{{length > 5}}"> 1 </view>
<view wx:elif="length > 2"> 2 </view>
<view wx:else> 3 </view>

hidden也可以控制元素的显示和隐藏,那么两者有什么区别呢

if在切换时框架会有个局部渲染的过程,确保条件块在渲染可以销毁便于进行进行渲染,hidden组件始终都会渲染。只是通过hidden属性,我们可以控制元素在视图上的显示和隐藏。所以说wx-if 有更高的切换消耗,而hidden有更高的初始化消耗,如果频繁切换显示的话是hidden更好

绑定事件

生命周期回调事件是不需要管理的,当生命周期回调事件发生的时候,小程序会自动调用

但是,绑定事件,是需要认为管理的。

绑定事件的写法是以key、value的形式存在的

key以bind或catch开头,然后跟上事件的类型

视图层

<view id='tapTest' data-hi='WeChat' bindtap='tapName'>Click me! </view>

逻辑层

page({
    tapname:function(event){
        console.log(event)
    }
})

模板引用

模板标签template

在template中定义了一个代码片段,那么属性代表了template的名称,在外面通过一个is属性声明我们想要的是哪个模板,这里的is也可以动态的进行数据绑定,data属性,向模板传递数据信息

需要注意的是模板拥有自己的作用域,只能通过data属性去传入。

除了模板引用,微信还提供了文件引用

文件引用

import include

所引用的模板文件,它的模板只能去渲染它对应的模板的内容

import作用域的概念:

只能引用目标文件所定义的的template模板,如果说目标文件嵌套了其他的文件的template模板,是不会被引用到的,避免了引用模板死循环的问题

和import不同的是,include是把目标文件内除了template代码块之外的所有代码引进来

以上就是import和include的区别


响应式像素


wxss和css的样式定义很像,但对css做了一些补成

设备像素:设备显示的最小物理单位,这些物理单位是显示屏上一个个点,这些点是固定不变的。

CSS像素:是外部编程概念,是css样式代码中所使用的逻辑像素。

PPI: 每英寸所拥有的像素数,数值越高,说明我们的显示屏越能以更高的密度去显示图像。公式:

DPR:指的是手机某一方向上设备像素和css像素之比

在做APP移动端开发,会使用rem,rem是根据HTML的根元素的font-size大小来适配的,但是wxss不能直接去操作HTML的样式属性,所以rem的适配方案就失效了。所以微信团队基于此推出了rpx,它规定了屏幕宽度为750个rpx,我们可以根据屏幕宽度进行自适应。其实rpx实现原理和rem原理是一样的,而且rpx最终也是转换成了rem。

样式

外联样式的引入:@import

如果样式index.wxss样式和外联样式有冲突,会采用index.wxss中的样式

内联样式:

内联样式可以绑定样式

所以一般来说,把静态样式写入class属性中,动态样式写入内联中绑定数据

选择器:

wxss支持的选择器:

优先级

慎用important,修改插件样式是可能会用到

WXML的学习就到这里了,从这里我们可以看到和HTML,CSS,前端的思想是一致的,在数据绑定这一模块和Vue是非常相似的。

逻辑层 js 视图层 wxml + wxss 总结

逻辑层主要负责数据、行为、路由

视图层主要负责结构、渲染、交互

逻辑层和视图层是通过数据绑定和事件回调进行互动的


小程序提供的能力和常用API


微信API

网络请求

HTTP请求

网络请求都是异步的

wx.request({
    url:'',
    data:{},
    header:{},
    method:'POST',
    success:function(res){
        console.log(res.data)
    },
    fail:function(res){}
})

我们放置这样一个按钮

<button bindtap="testNet">Test Net</button>

然后逻辑是这样的

testNet:function(event){
    wx.request({
      url: 'http://www.imooc.com',
      method:'GET',
      header:{},
      success:function(res){
        console.log(res.data)
      },
      fail:function(res){
        console.log('request failed')
      }
    })
  },
  tapName:function(event){
    console.log(123)
},

但是,我们可能会请求失败,可能的原因是不合法的域名,所以我们要勾选下面的选项:

这样我们就能正确的请求数据了。

网络请求的异步特性

假设我们将代码改成这样

testNet:function(event){
    var data = 'undefined'
    wx.request({
      url: 'http://www.imooc.com',
      method:'GET',
      header:{},
      success:function(res){
      console.log('in success')
        data = res.data
      },
      fail:function(res){
        console.log('request failed')
      }
    })
    console.log('data',data)
  },
  tapName:function(event){
    console.log(123)

最后输出的内容是

data:undefined
in success

我们可以看出是先打印的 data 后来又打印 success 函数的内容

因为 success 和 fail 的机制这样的,只有请求成功或者失败之后,才会调用相关的函数,在不满足的情况下,是不调用的。

代码都是直接运行下去的,直到成功或者失败才会运行函数。

文件上传、下载

上传文件

wx.uploadFile({
    url:'upload',
    filePath:'example.jpg',
    name:'file',
    formData:{
        'user':'test'
    },
    success(res){
        console.log(res.data)
    }
})

下载文件

wx.downloadFile({
    url:'download',
    header:{},
    filePath:'example.jpg',
    success(res){
        console.log(
            res.statusCode
        )
    }
})

*Task(网络任务对象)

异步任务提交以后,需要对任务进行操作的时候,使用Task对象

作用

中断任务
触发回调函数
关闭连接
其中Task的类别如下:
    RequestTask
    UploadTask
    DownloadTask
    SocketTask

本地存储

本地存储可以理解为本地缓存。

就是把数据存储在本地缓存中指定的key中,数据存储生命周期跟小程序本身一致。

一共有四个API

wx.setStorage
wx.getStorage
wx.removeStorage
wx.clearStorage

在 wxml 添加

<button bindtap="testStroage">test storage</button>

然后 .js 如下:

testStroage:function(event){
    wx.setStorage({
      key: 'test',
      data: 'data',
    })
    wx.getStorage({
      key: 'test',
      success: function(res) {
        var data = res.data
        console.log('data from storage',data)
      },
    })
},

里面的那些函数(getStorage、setStorage)都是异步的。

当然,缓存也有同步的,比如

wx.getStorageSysc(key)

文件系统

有一个全局的文件管理器,通过这个管理器,我们就能增删改查,以及对文件夹的操作。

获取全局唯一的文件管理器

var fs = wx.getFileSystemManager()

对文件进行操作的API有很多,完全覆盖编程语言对文件的各种操作。

fs.saveFile
fs.writeFile
fs.readFile
fs.removeSavedFile
fs.appendFile # 向文件追加内容

文件夹的操作

fs.mkdir
fs.rmdir
fs.isDirectory
fs.isFile

开放能力

用户数据

头像、昵称等公开信息——wx.getUserInfo()

openid等敏感数据

微信会为每一个用户赋予一个唯一的openid

这个流程图全程都是加密的。

推送数据

基于微信的通知渠道,小程序框架为开发者提供了可以高效触达用户的消息。

运营消息

帮助小程序进行迭代优化

登录小程序管理后台或者进入小程序数据助手

基础组件

视图容器

view
scroll-view
swiper
cover-view

基础内容

text
icon
rich-text

表单、导航

button
form
input

WeUI-WXSS

WeUI是一套同微信原生视觉体验一致的基础样式库

微信官方设计团队为微信内网页和微信小程序量身设计

包括button、view等众多元素

得到WeUI

在 Github 上搜索 weui-wxss 获取源码

我们也可以直接在手机上预览,扫描下面的二维码。

具体的使用方法,如下

在github上搜索相关的内容,然后下载下来

用微信web开发者工具打开dist目录(请注意,是dist目录,不是整个项目)。

我们把里面的 weui.wxss 拷贝到我们自己的项目,以我的为例

我在整个项目中,新建了一个文件夹,叫做 thirdparty

我们在app.wxss引入下面的代码

@import 'thirdparty/weui.wxss';

插入相应的组件

我们在github中下载下来的那个文件夹中,可以看到examples文件,里面存在大量的组组件源码。

我在项目中新增了一个文件夹,并且创建了相应的文件(demogrid)

我们在 app.json 中配置文件路径

然后将相应的代码复制到相应的文件,比如 .wxml 和 .js 文件的内容,复制到相应的后缀名文件里面


小程序对接Django


本地开发对接

小程序只能跟制定的域名进行网络通信

小程序必须使用 https 发起网络请求

远程部署测试

使用git远端同步代码

git的仓库

coding.net
oschina开源中国
码云

我们通过 git 仓库就能同步服务器代码,而不需要修改之后传到服务器上

管理依赖环境

我们把我们自己用的库写在 requirements.txt

等我们下次用的时候直接

pip install -r requirements.txt

例如:

Django==2.0
numpy==1.15

小程序的发布流程


请我喝杯咖啡吧~