写在前面:
- 作为一个刚刚入坑微信小程序的小白,以下是我在学习中的笔记,因为我真的太健忘了...
- 文章中可能会有错误,但是我会不断的修正的。
- 持续学习,持续更新...
- 谢谢浏览,如有错误烦请指正,喵喵喵~ (≧∀≦)ゞ
微信官方的小程序开发文档,可以说是非常有用了!
目录
1.目录结构详解
2.视图与渲染
3.微信小程序事件
4.微信小程序的配置
5.微信小程序APP的生命周期
6.APP对象的使用
7.微信小程序页面的生命周期
8.微信小程序页面的数据传递
1.目录结构详解
对于整个app:
app.json:配置了整个app的信息,pages和window的信息好像是必须要有的,也可以自己添加一个tabBar之类的
app.wxss:全局的样式设置,对于所有页面都通用的样式设置,就放在这里啦
app.js:全局的数据和逻辑,其他各个页面都可以访问到
对于页面:
pages文件夹里面包含的是具体的页面文件夹,例如名为index的页面,为该页面定制的文件夹里包括:
index.js:页面的逻辑处理和数据就在这里
index.wxml:页面的布局UI,包含哪些组件什么的
index.json:配置页面的入口(可以没有),可以覆盖app.json里面的某些东西
index.css:页面的样式文件,丰富页面效果
如果要自己创建一个项目:
- 建立app.json
- 然后创建一个page文件夹,里面装的是具体页面的文件夹(在每一个具体页面里面必须有.js和.wxml文件)
- 文件夹创建好了之后,在app.json里面配置页面的路径
- 在具体页面的js文件里面写page方法
补充:
.js文件常常让我看不懂,花括号、逗号、括号怎么在使用的看起来乱七八糟的,下面就剖析一下这个结构。
如果是缩句,.js文件最后可以缩写成一个方法,app.js就调用了一个函数App(),index.js就调用了一个函数Page()
当然这个方法是有参数的,参数包括一堆变量,一堆函数。
举例说明:
//这是一堆数据Page({ data: { text:'这里是内容哦...', show:true, textchange:'hello', news:['aaa', 'bbb', 'ccc','ddd','eee'] }})//这是一堆方法Page({ onLoad: function (options) { }, onReady: function () { }, onShow: function () { }, onHide: function () { }, onUnload: function () { }})可以观察到,结构是这样的:
page({ XXX1,XXX2,XXX3})所以在page()方法里面的参数用一对{ }来装这个参数们,参数与参数之间用逗号隔开,
进一步观察,
数据参数格式如下,类似于一个集合,集合名在最外面,然后:{ },在{ }里面装具体的数据,key:value的形式,数据间用逗号隔开
data:{ data1:xxx, data2:xxx, data3:xxx}函数参数格式如下,
函数名:function(){ var isShow=this.data.show this.setData({ show: !isShow}) }})在函数体里面的赋值用等号,末尾可以不用写分号,换行即可。
经过详细的拆分,再去看.js文件,就会觉得结构清晰很多啦~
2.视图与渲染
关于模板
在页面.wxml文件的使用
!--使用include导入模板相当于把文件里面的东西全部复制过来--!--src需要写入相对路径,前面两个点--include src="../templates/header.wxml" /!--使用Import导入模板,文件里面可以由多个模板,然后再下面指定导入的是哪一个--!--在模板文件中,只有用template标签包裹的,用name命名了的模板才可以被成功import--import src="../templates/footer" /template is="footer1"/模板文件(.wxml)
textI'm header.../text!--import引用作用域是有限制的,引用页面只能使用被引用页面的模板,不能使用被引用页面中引用其它页面模板的模板--!--如果模板A引用了模板B,页面引用模板A的时候无法引用模板B的部分--template name="footer1"I'm footer1/templatetemplate name="footer2"I'm footer2/template最后总结就是
- include 适合引入组件文件(全部复制过去)
- import 可以用来引用模板,在开发中可以避免相同模板的重复编写
- include 因为是全部复制过去就比较随意,在模板文件里随便怎么freestyle的写
- import 引用的模板必须要用template包裹,并且要设定模板的name属性
- 使用方法include、src配套使用,import、src、template、is配套使用
- 在src写路径的时候,相对路径的..是两个点,不是三个点
为按钮绑定点击事件
button type='primary' bindtap='btnclick' primary/buttonbindtap='btnclick'是关键,‘xxx’就是点击事件的名称。点击了要执行的行为在.js文件中实现。
btnclick:function(){ //点击按钮后执行的动作}TIPS:
Page({ data: { show:true, textchange:'hello', news:['aaa', 'bbb', 'ccc','ddd','eee'] }, btnclick:function(){ var newsdata=this.data.news this.setData({news:newsdata}) }})在函数中引用的变量,如果不是在函数体里面定义的,都需要指向,例如var newsdata=this.data.news,直接用变量名是访问不到的,会报thirdScriptError错误。
条件渲染:
!--条件渲染,true or false--view wx:if="{{true}}"{{text}}+2/viewview wx:if="{{false}}"{{text}}+3/viewview wx:if="true"{{text}}+4/viewview wx:if="false"{{text}}+5/viewif里面是true就会显示,是false就不显示。
有没有发现view wx:if="false"{{text}}+5/view依然显示了~ 所以要细心,我解释不清楚,但是很能理解为什么会这样,有过其他编程语言基础的朋友应该也能get。
view wx:if="{{show}}"111111111/viewview wx:else2222222222222/viewif-else同理,不多解释啦。
循环标签(灵活地使用它,可以减少很多代码量哦~~)
!--循环标签--!--item表示一条数据,可以改其名称,新名称也要符合命名规范--!--index表示数据项的编号--view wx:for="{{news}}" wx:for-item="itemx"循环内容... {{itemx}}...{{index}} /viewPage({ data: { news:['aaa', 'bbb', 'ccc','ddd','eee'] }})在循环标签中,index和item都是特殊字,item表示一条数据,index表示数据项的编号。
wx:for-item="itemx"就是在改变名称,改了之后itemx就表示一条数据
以上代码运行效果:
如果一次需要循环很多数据怎么办呢??比如,循环一次,我既要得到A信息,又要得到B信息,该怎么操作??
答案就是在.js中定于数据的时候如下定义,{ }里面就是一条数据
Page({ data: { info:[ { suject:"语文", score:"95" }, { suject: "数学", score: "99" }, { suject: "英语", score: "100" } ] }})读取数据的时候用item.A读取A数据,item.B读取B数据
view class='content' view wx:for="{{info}}" text科目:{{item.suject}}/text text成绩:{{item.score}}/text /view/view3.微信小程序事件
事件可以理解为是一种用户行为,一种通讯方式。我学过Java,里面的事件监听应该和这个是同理的。
事件可以分为冒泡事件和非冒泡事件。什么是冒泡事件呢?冒泡事件就是当点击子view,会触发其父view的点击事件。还看不懂也没关系,下面的实验会让你一目了然~
冒泡事件包括:
- 点击事件 tap
- 长按事件 longtap
- 触摸事件 touchstart touchend touchcancel touchmove(touchend是正常结束触摸,touchcancel是意外结束)
- 其他 submit input...
接下来做一个小实验:
view class='view1' bindtap='click1' id='view1' data-id="100" data-title="新闻标题" view11 view class='view2' bindtap='click2' id='view2' view22 view class='view3' bindtap='click3' id='view3' view33 /view /view/view(得到了这幅丑丑的图,wxss文件略,值得注意的是view之间的嵌套关系)
为各个View设置点击事件
//当事件执行的时候,会把事件传递进来,也就是event click1:function(event){ console.log("view1"); console.log(event); }, click2: function () { console.log("view2"); }, click3: function (event) { console.log("view3"); console.log(event); }当我点击view3的时候,日志如下:
我明明只点击了View3,为什么view2,view1也触发了点击事件呢??这就是冒泡事件,当点击子view,会触发其父view的点击事件。
值得注意的是,我绑定点击事件的方式是用的bindtap。
换一个方式绑定点击事件,用catchtap。
view class='view1' catchtap='click11' view11 view class='view2' catchtap='click22' view22 view class='view3' catchtap='click33' view33 /view /view/view就不会冒泡了,日志图我就省略了。
事件的对象:
- 类型type
- 时间戳timeStamp
- 事件源组件target
- 当前组件currentTarget
- 触摸点数touches
主要了解的是currentTarget和target,解释不清楚了,直接做实验。接着刚才的那个实验,我们详细的观察日志信息:
4.微信小程序的配置
话不多说,先甩一个官方的链接!(关于配置的帮助文档~)
作为一个零基础的小白,我的第一个问题是配置什么啊??
- app的页面配置
- app的窗口配置
- app的tabBar配置
- 网络超时配置
- debug开启配置
我的第二个问题是在哪里配置啊??
是在app.json里面配置哦!!
好了,我不再加戏了,直接上干货吧。
(.json文件里面是不能加注释的,为了看起来清晰,我后来强加了注释~~喵喵喵)
{ //app的页面配置!!! "pages":[ "pages/index/index", "pages/logs/logs" ], //app的窗口配置!!! "window": { "navigationBarBackgroundColor": "#ffffff", "navigationBarTextStyle": "black", "navigationBarTitleText": "Demo", "backgroundTextStyle": "light" },//app的tabBar配置!!! "tabBar":{ "color":"#333", "list":[{ "pagePath":"pages/index/index", "iconPath":"images/icon1.png", "selectedIconPath":"images/icon11.png", "text":"目录" },{ "pagePath": "pages/logs/logs", "iconPath": "images/icon2.png", "selectedIconPath": "images/icon22.png", "text": "我的" }] },//网络超时配置 "networkTimeout":{ "request":10000, "downloadFile":10000 },//debug开启配置 "debug":true}
一些小小的补充:
- pages里面是配置各个页面的路径,顺序也是有一点考究的哦,第一个页面就是app进入的第一个页面。
- tabBar就是上图那个东东,应用很广的,不过具体高度,icon大小设置这些我还没摸清楚,之前用androidstudio也做过一个tabBar,比这个复杂太多太多了,小程序几行代码就搞定,666,不过具体样式的设计改起来好像不太容易。
- debug模式开启了之后,小程序运行过程可以在console里面看到详细的日志信息。
- 官方的帮助文档详细的列出了可以配置哪些属性,have a try~~
5.微信小程序APP的生命周期
话不多说,直接上关键代码:
//appConfig是变量,里面的内容包含一些方法(onLaunch...)和对象(globalData...)var appConfig = { onLaunch: function () { console.log("--onLaunch--") }, onShow: function () { console.log("--onShow--") }, onHide: function () { console.log("--onHide--")}, onLoad: function () { console.log("--onLoad--")},}App(appConfig)查看日志:
第一步:onLaunch,第二步:onLaunch
切后台:--onHide--(页面只是隐藏了,并没有删除)
从后台切回前台:--onShow--
6.APP对象的使用
app.js里面可以定义一些全局的方法和对象。
具体某一个页面如何调用呢?
第一步先const app = getApp(),然后再app.xxx得去调用。
来一波实验:
//app.js//自己定义数据var appConfig = { myData: { myusername:"hahahan" }}App(appConfig)//在index.js里面访问const app = getApp()Page({ onLoad: function () { var getdata=app.myData.myusername }})7.微信小程序页面的生命周期
做一个小实验
小实验的内容概括:
- 创建两个页面index和logs
- 为这两个页面的生命周期函数中添加打印日志信息的语句
- 为index设置点击事件使其可以跳转到logs
- 从logs页面返回到index
- 观察伴随一系列操作,日志的变化情况
//index.wxml页面view class="container" view class="myclass" text bindtap='itemClick'Part1/text /view view class="myclass" text bindtap='itemClick'Part2/text /view view class="myclass" text bindtap='itemClick'Part3/text /view view class="myclass" text bindtap='itemClick'Part4/text /view/view//index.jsPage({ onLoad: function (options) { console.log("--index--onLoad--") }, onReady: function () { console.log("--index--onReady--") }, onShow: function () { console.log("--index--onShow--") }, onHide: function () { console.log("--index--onHide--") }, onUnload: function () { console.log("--index--onUnload--") }, //实现页面跳转 itemClick:function(){ wx.navigateTo({ url: '../logs/logs', }) }})//另一个页面logs.wxmlview class="container log-list" texthello!!hello!!hello!!/text/view//logs.jsPage({ onLoad: function (options) { console.log("--logs--onLoad--") }, onReady: function () { console.log("--logs--onReady--") }, onShow: function () { console.log("--logs--onShow--") }, onHide: function () { console.log("--logs--onHide--") }, onUnload: function () { console.log("--logs--onUnload--") }})//app.js(并不是完整代码)App({ onLaunch(){ console.log("--app--onLaunch--") }, onLoad(){ console.log("--app--onLoad--") }, onReady() { console.log("--app--Ready--") }, onShow() { console.log("--app--Show--") }})启动app
先启动app,然后启动了第一个页面。onLoad加载数据,onShow绑定数据
点击页面跳转
可以观察到,index页面被隐藏了,logs页面加载并显示
点击返回
logs页面被回收了,index页面显示
值得注意的是,之前实现页面跳转是用的navigateTo方法,现在换一个方法实现跳转试试,用redirectTo:
itemClick: function () { wx.redirectTo({ url: '../logs/logs', }) }点击index页面
发现index页面不是被隐藏而是被卸载了,页面无法返回。
进一步,添加一个tabBar实现跳转试试会怎样?
//app.json添加tabBar"tabBar": { "color": "#333", "list": [ { "pagePath": "pages/index/index", "text": "index" }, { "pagePath": "pages/logs/logs", "text": "logs" } ]}初始在index页面,点击logs按钮跳转至logs页面:
index页面被隐藏了,logs页面显示,那么再点击一下index:
logs页面被隐藏,index页面显示
8.微信小程序页面的数据传递
实验目标:从index页面转到logs页面,index页面的数据传到logs页面。
方法1:(使用bindtap实现跳转)
传递数据:
itemClick: function () { wx.redirectTo({ url: '../logs/logs?data=100', })}在Url地址后面加?携带数据。
接收数据:
目标页面在onload的时候可以接收数据:
onLoad: function (options) { console.log("--logs--onLoad--") console.log(options) }onLoad包含options对象,打印options内容如下:
所以,要在跳转后的页面访问传递的数据通过options即可。上述例子,通过option.data就可以访问到传递的数据。
方法2:(使用navigator实现跳转)
传递数据:
navigator url='../logs/logs?data=100' view class="myclass" textPart1/text /view /navigator接收数据和上述方法一样。
如果想要页面跳转了不能返回,则只需要添加redirect即可。
navigator url='../logs/logs?data=100' redirect多个数据传递,数据间用&连接:
navigator url='../logs/logs?data=100 & id=100 & x=100' redirect













