1、介绍
最近由于工作原因,接触了一些小程序项目开发,抽时间进行了一下基础知识整理,权当笔记记录吧,全文就是一个上手知识梳理,如果是已经比较熟悉的朋友,本文不会给你带来多少帮助。大多数内容官方文档中都有,本文做一些集中梳理以及个人理解,如需更深入了解,建议还是全面学习一下官方文档,或者等到使用的时候再去了解。谢谢!
官方文档链接
本文假设你对html、JavaScript、css、json等web基础有一定的了解。
微信小程序实际上是利用微信这个载体,让企业或个人拥有类似手机App的使用体验及服务。就是说小程序是依托于微信来运行的,同时它天生就能使用微信的一些API,比如微信登录、获取用户信息,微信发票、支付等等。
动手第一步就是先注册一个小程序,然后再安装官方提供的微信开发者工具。这个步骤没有什么难度,可直接按照官方文档进行。
2、基础
文件结构
小程序页面文件结构由下面四种文件组成,每个页面包含这四个文件,四个文件的路径与名字必须相同,就是说每个页面的这四个文件都放到一起,名字取一样的,只是后缀不同。
-
.json后缀的JSON配置文件
-
.wxml后缀的WXML模板文件,就是WEB开发的HTML一样的,这个是WeiXin Mark Language,微信ML,好理解吧。
-
.wxss 后缀的 WXSS 样式文件,就是WEB开发的CSS一样的,样式文件,这个是微信SS。
-
.js 后缀的 JS 脚本逻辑文件
基本上重要的文件就是wxml与js两个文件,一个是画页面的代码,一个是给页面绑定数据的逻辑代码。另外wxss就是样式。页面wxml中数据的绑定全部是通过js里面的page这个构造器里面的data属性来绑定的。
// demo.js
page({
data:{
name: '张三'
}
})
上面例子中的这个name,在页面上使用就是这样写:{{name}},页面上的所有变量,都是data里面的一个元素。直接两对大括号括起来,就绑定上了。js里面如果有对这个name修改的逻辑,页面上也会跟着变化。
每个页面都是需要在.js
里面的Page()
构造器来注册页面信息的,初始化data数据、逻辑等。
每个小程序还有3个全局文件,app.js,app.json,app.wxss
,有点类似于页面的那四个文件,这三个文件必须放到小程序的根目录下,其中app.js里面有个App实例,你在全局都可通过getApp()
获取该对象,然后调用他的方法。app.json里面有个pages数组,配置的是所有页面的路径信息,这个数组里面配到第一个的页面默认就是小程序的首页,打开小程序时的第一个页面。
app.js: 逻辑
app.json:公共配置
{
“pages”:[
"pages/index/index", // 这个数组第一个元素就是小程序的首页
"pages/index/query"
]
}
app.wxss:公共样式
生命周期
这个是官网的图片,了解一下就行,生命周期有几个过程方法,意思是,在这个生命周期中到哪一步了,哪个对应的方法就会被调用,比如onLoad,就是加载的时候就会进这个方法,在里面写初始逻辑就行了。
启动过程
小程序启动之后,app.js
的onLaunch
方法被执行;
而进入页面就是根据.json .wxml .wxss .js中的page()
构造器构造页面,渲染完页面后js里面的onLoad
被执行;
常用语法
数据绑定
<!--wxml-->
<view> {{message}} </view>
// page.js
Page({
data: {
message: 'Hello MINA!'
}
})
条件渲染
<!--wxml-->
<view wx:if="{{view == 'WEBVIEW'}}"> WEBVIEW </view>
<view wx:elif="{{view == 'APP'}}"> APP </view>
<view wx:else="{{view == 'MINA'}}"> MINA </view>
// page.js
Page({
data: {
view: 'MINA'
}
})
列表渲染
<!--wxml-->
<view wx:for="{{array}}"> {{item}} </view>
// page.js
Page({
data: {
array: [1, 2, 3, 4, 5]
}
})
循环中当前项的下标变量名默认为 index,当前对象变量名默认为 item;正常情况下不用写,直接使用{{item}},如果item是对象,那就是{{item.属性名}}。
也可以使用 wx:for-item
指定数组当前元素的变量名,使用 wx:for-index
指定数组当前下标的变量名;建议正常情况下可以不用。
模板
<!--wxml-->
<template name="staffName">
<view>
FirstName: {{firstName}}, LastName: {{lastName}}
</view>
</template>
<template is="staffName" data="{{...staffA}}"></template>
<template is="staffName" data="{{...staffB}}"></template>
<template is="staffName" data="{{...staffC}}"></template>
// page.js
Page({
data: {
staffA: {firstName: 'Hulk', lastName: 'Hu'},
staffB: {firstName: 'Shang', lastName: 'You'},
staffC: {firstName: 'Gideon', lastName: 'Lin'}
}
})
模板的意思就是,如果页面中有一部分与其他页面是一样的,那你就可以抽出来这部分做成一个模板,然后在用的地方直接使用模板名字作为标签,给他传数据就行。
事件绑定
事件绑定的搞法就是在组件上用bind+事件名来绑定事件,例如bindtap="onTap"
就是绑定点击事件,点击组件后绑定的事件方法onTap
就会被执行,事件方法被调用时会携带事件参数,可以打印出来看一下,如果需要传参数给事件方法,需要data-参数名的方式,例如data-test="{{id}}"
,在事件方法中通过const test= e.currentTarget.dataset.test;
获取传过来的参数值,可以传多个参数,就是再写一个data-test1。
上面的e就是事件对象,e.target
与e.currentTarget
区别:
target
是触发事件的组件对象,currentTarget
是当前绑定事件的组件对象,如果没有发生事件传递的时候,这两个是相同的,如果有事件传递,事件绑定在父组件上面,点击子组件,这时候currentTarget
是父组件对象,target
是子组件对象。
<view id="tapTest" data-test="Weixin" bindtap="onTap"> Click me! </view>
Page({
onTap: function(e) {
console.log(e)
const test= e.currentTarget.dataset.test;
}
})
事件冒泡(事件传递)
冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。tap
,longtap
,touchstart
,touchend
等。举个例子就是,比如我有一个商品列表,我在每行商品信息(有订单号、商品名称等一些内容)上面绑定了一个事件,点击查看商品详情(注意是在这一行上面绑定),同时我在订单号上面绑定一个点击复制订单号的事件,如果不阻止事件冒泡的话,点击订单号既会触发复制订单号事件,又会触发查看商品详情事件。这就是发生了事件冒泡。
非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。submit
,input
,scroll
这几个也很好理解,submit是提交的意思,一般提交后会有页面跳转或者业务结束,此时正常思维理解都不需要冒泡,所以这种事件,直接设计为天生不冒泡事件。
阻止事件冒泡:catchtap
,用catch绑定事件,抓住、捕获,不让再往下走的意思,很好理解。就是用catch代替上面的bind来绑定事件。
事件互斥:mut-bind
,使用mut-bind
绑定的事件,只会有一个触发。
事件捕获:查看官方文档。
具体有哪些事件,可以看组件对应的文档,不同的组件会支持不同的事件。
页面跳转
API | 说明 |
---|---|
wx.switchTab | 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面 |
wx.reLaunch | 关闭所有页面,打开到应用内的某个页面 |
wx.redirectTo | 关闭当前页面,跳转到应用内的某个页面 |
wx.navigateTo | 保留当前页面,跳转到应用内的某个页面 |
wx.navigateBack | 关闭当前页面,返回上一页面或多级页面 |
注意
navigateTo
, redirectTo
只能打开非 tabBar
页面。
switchTab
只能打开 tabBar
页面。
reLaunch
可以打开任意页面。
页面底部的 tabBar
由页面决定,即只要是定义为 tabBar
的页面,底部都有 tabBar
。
调用页面路由带的参数可以在目标页面的onLoad
中获取。
wx.navigateTo({
url: '/pages/order/order?billCode='+billCode,
})
onLoad(options){
const billCode = options.billCode
}
界面交互
API | 说明 |
---|---|
wx.showToast | 显示消息提示框 |
wx.showModal | 显示模态对话框 |
wx.showLoading | 显示 loading 提示框 |
wx.showActionSheet | 显示操作菜单 |
wx.hideToast | 隐藏消息提示框 |
wx.hideLoading | 隐藏 loading 提示框 |
3、小技巧
开源UI的使用技巧:一般开源的一些UI可以直接复用到自己的小程序中,他的演示程序与代码有一定的关联性,我经常用的一个叫color-ui组件库,这个作者写的比较规范,熟悉了以后,很好用。https://github.com/weilanwl/ColorUI,文字不太好传达使用技巧。
微信开发者工具:这个工具做小程序开发时还比较好用,渲染快。他跟谷歌浏览器一样有一个用于调试的工具,其中有一个AppData的地方可以看到页面的data对象里面实时数据,还要一个Storage可以看到你设置到缓存里面的数据。
4、避坑
1、Ios
手机时间格式不支持中杠-
转换,要使用斜杠/
。new Date()
2、如果新做一个页面的时候,需要在app.json
文件中pages
里面配置页面的路径,如果没有配置,在开发者工具中也能正常使用,使用手机时就会打不开页面,没有反应。
3、在任何会有异常节点的方法中一定要写catch,如果不写,经常出问题的时候什么反应都没有。
4、避免使用0和1作为一些状态码。因为if逻辑判断时0就是false,而前端有时候if(obj)仅仅是想要判断他不为空。
5、双等号比三等号好用。前后端分离开发,后端定义的状态值,Boolean值,字符码,通常不是很规范。使用双等号就不会有什么问题。(个人见解)
6、wx.showToast
有字数限制,最多7个字。
7、时刻注意异步请求与同步请求的差异,写逻辑代码的时候,不注意异步请求,经常会出现的效果与想的不一样。
8、array的常用方法熟悉一下。前端经常需要对后端返回数据进行处理,array是个好东西。
9、dataset事件传参大小写问题。中杠自动转为驼峰,驼峰大写自动转为小写。
data-element-type ,最终会呈现为 event.currentTarget.dataset.elementType data-elementType ,最终会呈现为 event.currentTarget.dataset.elementtype
10、样式文件覆盖。
样式出现重复的时候,有优先级,这个可以了解一下,有好处。
以上就是本次分享的内容,感谢大家支持。您的关注、点赞、收藏是我创作的动力。
万水千山总是情,点个 👍 行不行。