admin管理员组文章数量:1569942
wx小程序笔记
- 第一章:小程序前奏
- 第一节:账号和软件
- 第二章:小程序基础
- 第一节:项目结构
- 第二节:配置
- 第三节:WXML语法
- 数据绑定(js数据)
- 条件渲染(判断)
- 列表渲染(循环)
- wx:key作用:
- 模板
- include
- 案例:99乘法表
- 第五节:事件
- 绑定事件:
- 获取元素上的数据:
- 事件冒泡和事件捕获:
- 第六节:WXSS语法
- WXSS和CSS:
- rpx尺寸单位:
- 样式导入:
- 第七节:flex布局
- 案例:
- 基本概念:
- 设置在主轴上的排列方式:
- 设置在侧轴上的排列方式:
- 更换主轴和侧轴方向
- 换行
- align-content属性
- 元素(子容器)的相关属性
- flex-basis:
- flex-grow:
- flex-shrink属性:
- flex属性:
- 第八节:APP对象
- onLaunch(options):
- onShow(options):
- onHide():
- onError(String error):
- onPageNotFound(Object):[有bug]
- getApp():
- 第九节:Page对象
- Page对象作用:
- 数据渲染:
- Page生命周期函数:
- onLoad(Object query):
- onShow():
- onReady():
- onHide()
- onUnload()
- 路由:
- 第十节:WXS语法
- wxs代码:
- require函数:
- 变量:
- 注释:
- 运算符:
- 语句:
- 数据类型:
- 内置类库:
- wxs案例:
第一章:小程序前奏
第一节:账号和软件
- 账号注册:
进入 注册一个微信小程序账号,然后输入邮箱注册账号。一个邮箱只能注册一个微信公众平台账号(比如小程序、公众号等)
注册的时候,先选择个人用户即可。目前为止是足够了。如果你有工商营业执照,也可以创建企业账号。企业账号能拥有的功能会更多,比如支付等。注册完后,后面会出现一个二维码,让你扫描这个二维码来绑定你的微信账号。一个微信账号只能绑定5个微信公众平台账号。 - 开发工具:
微信官方开发工具。下载链接
Visual Studio 1.28。下载链接 - 开发工具介绍
开发工具下载地址
微信官方开发者工具详细教程:教程地址
第二章:小程序基础
第一节:项目结构
创建完一个新的项目后。会出现以下的目录结构:
- project.config.json:项目的配置文件。比如设置项目的名字,设置appid等。
- app.js:小程序逻辑处理。比如小程序加载完成执行的代码。
- app.json:小程序公共配置。比如小程序的页面,是否有tabbar等。
- app.wxss:小程序公共样式。在这个里面写的样式可以被所有页面使用。
- pages:存储小程序页面的。
- index:页面的名称
- index.js:index页面的逻辑处理文件。
- index.json:index页面的配置文件。
- index.wxml:index页面的页面结构。
- index.wxss:index页面的样式。
- 其他页面
一个微信小程序就是由以上几个部分组成的。如果熟悉网站前端开发的同学肯定都知道。在前端中存在html
、css
、js
,其实就分别对应的是小程序中的wxml
、wxss
、js
文件。其中小程序中的wxml
中的标签和语法,稍微和html
有点不一样。wxss
语法采用的都是大部分的css
语法,并且增加了导入的功能。所以如果你对前端比较熟悉,学习微信小程序开发就非常简单了。
- index:页面的名称
第二节:配置
官方文档-全局配置
- 小程序根目录下的
app.json
文件用来对微信小程序进行全局配置
官方文档-页面配置
- 每一个小程序页面也可以使用
.json
文件来对本页面的窗口表现进行配置。页面中配置项在当前页面会覆盖app.json
的window
中相同的配置项。
官方文档-sitemap 配置
- 小程序根目录下的
sitemap.json
文件用于配置小程序及其页面是否允许被微信索引,文件内容为一个 JSON 对象,如果没有sitemap.json
,则默认为所有页面都允许被索引
(其他)
- 创键页面快捷方式:右键pages文件夹——创建文件夹——右键新建文件夹——创建page——生成页面的js,json,wxml,wxss文件,在app.json文件中自动添加路径
- icon图标:下载地址
第三节:WXML语法
微信官方教程
- 布局的方式跟HTML是一模一样的。
- 标签的名字不再是传统的HTML的了,而是使用微信自己定义的一套,所以写代码的时候完全使用之前写HTML的方式去写,只不过改个标签名就可以了。
- WXML的语法,和一些模板语法比如Django中的模板语法非常的类似。
数据绑定(js数据)
- 使用双大花括号。
- 获取对象的值,通过下标获取数组中的值。
- 可以做运算,比如判断,四则运算等。
- 总而言之一句话:需要使用js中传过来的值,就必须使用双大花括号。
- wxml文件中数据是从js文件中传来的
js文件中page
属性中date
:
Page({
data: {
username:"微信",
person:{
"username":"weixin",
'age':20
},
books:[
'三国演义',
'水浒传'
],
weather:'晴天'
},
onLoad: function () {
},
})
wxml文件中
<view > {{username}}</view>
<view > {{person.username}}</view>
<view > {{books[0}}</view>
- 需要双大括号获取属性
{{ XXX }}
,双大括号中可以进行四则运算,括号外则为正常文本
<view > {{18+10}}</view><!-- 28 -->
<view > {{18}}+10</view><!-- 18+10 -->
条件渲染(判断)
- view标签中添加
wx:if="{{condition}}"
;wx:elif="{{condition}}"
;wx:else
属性- 其中
elif
相当else if()
- 条件放在双大括号中
{{condition}}
,不放则条件永远为truewx:if='condition'
- 两个属性标签中不可以有其他标签
- 可以在条件标签内添加组件
- 其中
ex:
<view wx:if="{{18>18}}">
可以进入网吧
</view>
<!-- <view></view>不可以有 -->
<view wx:elif="{{18==18}}">
刚刚好可以进入
</view>
<view wx:else="{{18<18}}">
不可以进
<view>啦啦啦</view>
<view>啦啦啦</view>
</view>
- 需要多组件渲染使用
block
标签属性:wx:if="{{condition}}"
;wx:elif="{{condition}}"
;wx:else
- 如
"{{weather == '晴天'}}"
,晴天外要使用’否则会报错
- 如
ex:
<block wx:if="{{weather == '晴天'}}">
<view>因为晴天,难得的好天气</view>
<view>会选择长途旅行</view>
</block>
<block wx:else>
<view>因为阴天</view>
<view>会选择在家</view>
</block>
列表渲染(循环)
- 标签内属性
wx:for="{{[1,2,3,4,5]}}"
- 双大括号中[ ]为数组
{{item}}
为数组元素{{index}}
为数组元素下标
ex:
<view wx:for="{{['a','b','c','d']}}">
{{item}}/{{index}}
</view>
- 属性:
wx:for-item="ele"
给元素从命名,wx:for-index="idx"
下标名称
ex:
<view wx:for="{{['a','b','c','d']}}" wx:for-item="ele" wx:for-index="idx">
{{item}}/{{index}}
</view>
- 也可以使用block标签
ex:
<block wx:for="{{['a','b','c','d']}}">
<view>{{item}}</view>
<view>{{index}}</view>
</block>
wx:key作用:
如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如 <input/>
中的输入内容,<switch/>
的选中状态),需要使用 wx:key
来指定列表中项目的唯一的标识符。
wx:key
的值以两种形式提供:
- 字符串或者数字,代表在
for
循环的array
中item
的某个property
,该property
的值需要是列表中唯一的字符串或数字,且不能动态改变。在写的时候,直接写这个property
的名字就可以了,不需要写item.property
的形式,并且不需要加中括号。 - 保留关键字
this
代表在for
循环中的item
本身,这种表示需要item
本身是一个唯一的字符串或者数字,如:
当数据改变触发渲染层重新渲染的时候,会校正带有key
的组件,*框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。 - 及时列表中的组件没有发生状态改变,那么也建议使用
wx:key
。因为如果不使用,那么以后重新渲染的时候,就会把之前组件销毁掉,然后重新创建,性能会很低。
如不提供 wx:key
,会报一个 warning
, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。
ex:
- js文件:
// pages/wxmlKey/wxmlKey.js
Page({
data: {
lines:[{
"id":1,
"name":'switch1'
},{
"id":2,
"name":'switch2'
},{
"id":3,
"name":'switch3'
},{
"id":4,
"name":'switch4'
}]
},
tapEvent:function(event){
var lines = this.data.lines;
lines.splice(0,0,{
"id":5,
"name":'switch5'
});
//this.data.lines = lines;//js中data的值会改变但是页面不会
this.setData({
lines:lines
})
}
})
- wxml文件:
<view wx:for="{{lines}}">
<switch>{{item.name}}</switch>
</view>
<button bindtap="tapEvent">更新</button>
- 样式:
- 点击更新:
注:当组件发生改变时,选中项也会发生改变 - 添加
wx:key
:选项就不会随之改变
<view wx:for="{{lines}}" wx:key="id">
<switch>{{item.name}}</switch>
</view>
<button bindtap="tapEvent">更新</button>
- 注意
key:
中选中唯一的引用就行,直接写属性名字就行,如id
- 如果
lines
的值为[1,2,3,4,5]
,key
中tem
替换成*this
- 即便没有发生组件改变也应该添加
wx:key
,能提高效率
模板
有些时候,一段布局代码我们需要在多个地方使用,那么我们可以将其定义成模板,然后把变量单独抽取出来,通过调用模板的时候再传递过去。示例代码如下:
调用模板:
在传递变量的时候第三节:WXML语法,如果是直接从js
文件中获取到的,那么可以通过...item
的方式来展开显示。示例代码如下:
另外,如果想使用模板的样式文件,也需要在wxss
文件中导入模板的wxss
文件。示例代码如下:
ex:
模块文件:
- message.wxml文件
<template name="message">
<view class="message-group">
<text class="content">{{content}}</text>
<text class="friend">{{friend}}</text>
<text class="time">{{time}}</text>
</view>
</template>
- message.wxss文件
.message-group{
height: 60px;
line-height: 60px;
padding: 10px;
border-bottom: 1px solid #e4e4e4;
}
.message-group .content{
float: left;
}
.message-group .friend{
float: right;
font-size: 12px;
color: burlywood;
}
page文件:
- qq.js
// pages/tpl/qq/qq.js
Page({
data: {
messages:[
{
'content':"今天我们上网吧!",
'friend':"夏明",
'time':"2020/02/18"
},{
'content':"今天我们打台球吧!",
'friend':"小华",
'time':"2020/02/17"
},{
'content':"今天我们学习吧!",
'friend':"秋田",
'time':"2020/02/14"
},{
'content':"今天我们做梦吧!",
'friend':"李明",
'time':"2020/01/18"
},{
'content':"今天我们聚会吧!",
'friend':"陶琪",
'time':"2020/02/18"
}
]
}
})
- qq.wxss
@import "../../../templates/message/message.wxss";
- qq.wxml
方法一:
<import src="../../../templates/message/message.wxml"/>
<template is="message" wx:for="{{messages}}" data="{{content:item.content,friend:item.friend,time:item.time}}"></template>
方法二:
<import src="../../../templates/message/message.wxml"/>
<template is="message" wx:for="{{messages}}" data="{{...item}}"></template>
其他:
- tpl:模板的简写
include
如果一段代码是不需要填入动态的数据,那么可以直接使用include把这段代码引入到其他的地方。示例代码如下:
banner.wxml中的代码:
<view>
我是一个banner
<text>{{username}}</text>
</view>
qq.wxml中的代码:
<include src="./banner.wxml"/>
qq.js中代码:
Page({
data: {
username:'Wangbr'
}
})
注意:include 可以将目标文件除了 <template/>
<wxs/>
外的整个代码引入,相当于是拷贝到 include 位置
案例:99乘法表
wxml文件:
<view class="row" wx:for="{{[1,2,3,4,5,6,7,8,9]}}" wx:for-item="v1" wx:for-index="i">
<view class="col" wx:for="{{[1,2,3,4,5,6,7,8,9]}}" wx:for-item="v2" wx:for-index="k" wx:if="{{i>=k}}">
{{v1}}*{{v2}}={{v1*v2}}
</view>
</view>
wxss文件
.row{
display: flex;
justify-content: flex-start;
font-size: 8px;
}
.row .col{
width: 40px;
}
第五节:事件
绑定事件:
在组件上使用bind:事件名称="执行的函数"即可绑定事件。然后可以在js文件中,实现具体的执行的函数。以后在这个组件上发生了bind后的事件,那么就会触发js中的函数了。示例代码如下:
<view bind:tap='onViewClick'>
点击我
</view>
<view bindtap="onViewClick">
请点击我
</view>
在js代码中:
Page({
data: {
},
onViewClick:function(event){
console.log('hello,boy');
},
})
跳转方法:
page({
// gotoNextpage 名字可以随意
gotoNextpage:funcion(event){
wx.navigateTo({
url:'/pages/...',
})
}
})
获取元素上的数据:
我们能捕获到点击事件还不够,我们在点击的时候还要获取一些数据。比如文章列表,我点击了某个文章列表的容器,我想获取这个容器的对应的文章,那么就需要把这个文章的id绑定到view上面,以后我在点击的时候,这个数据再通过event参数传递给后台的js函数。绑定数据的时候,我们需要通过data-数据名的方式绑定。示例代码如下:
wxml如下:
<view class="article-group" wx:for='{{articles}}' wx:key="id"
bind:tap='onArticleClick' data-id="{{item.id}}" data-title="{{item.title}}">
{{item.title}}
</view>
js代码如下:
Page({
data: {
articles:[{
'id':1,
"title":"钢铁是怎样炼成的"
},{
'id':2,
"title":"互联网风口推动者的生意"
}]
},
onArticleClick:function(event){
console.log(event);
var dataset = event.currentTarget.dataset;
console.log(dataset);
},
})
wxss如下:
.article-group{
font-size: 14px;
height: 40px;
padding: 10px;
line-height: 40px;
border-bottom: 1px solid #e4e4e4;
}
事件冒泡和事件捕获:
绝大部分小程序定义好的事件都是冒泡的。冒泡是什么意思呢,就是点击一个子元素,如果事件是冒泡的,那么这个事件也会传递给父元素。如在下边这个例子中,点击inner view
会先后调用handleTap2和handleTap1。
<view id="outer" bindtap="handleTap1">
outer view
<view id="inner" bindtap="handleTap2">
inner view
</view>
</view>
如果我们想要阻止事件的冒泡。我们可以以catch
开头来定义一个事件。这样就可以拦截事件的冒泡了。如在下边这个例子中,点击inner view
会先后调用handleTap3
和handleTap2
(因为tap事件会冒泡到middle view
,而middle view
阻止了tap事件冒泡,不再向父节点传递),点击middle view会触发handleTap2,点击outer view会触发handleTap1。
<view id="outer" bindtap="handleTap1">
outer view
<view id="middle" catchtap="handleTap2">
middle view
<view id="inner" bindtap="handleTap3">
inner view
</view>
</view>
</view>
target和currentTarget区别:
<view id="outer" bindtap="handleTap1">
outer view
<view id="inner" bindtap="handleTap2">
inner view
</view>
</view>
拿这个例子来讲,如果点击了inner view,那么在handleTap2中target和currentTarget指向的都是同一个对象,而在handleTap1中,则target指向的是inner view,currentTarget指向的是outer view。
第六节:WXSS语法
WXSS和CSS:
WXSS(WeiXin Style Sheets)具有CSS大部分特性。同时为了更适合开发微信小程序,WXSS对CSS进行了扩充以及修改。主要体现在两个方面:
尺寸单位。
样式导入。
rpx尺寸单位:
可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx
。如在iPhone6上,屏幕宽度为375px
,共有750个物理像素,则750rpx = 375px = 750物理像素
,1rpx = 0.5px = 1物理像素
。
设备 | rpx换算px (屏幕宽度/750) | px换算rpx (750/屏幕宽度) |
---|---|---|
iPhone5 | 1rpx = 0.42px | 1px = 2.34rpx |
iPhone6 | 1rpx = 0.5px | 1px = 2rpx |
iPhone6 Plus | 1rpx = 0.552px | 1px = 1.81rpx |
样式导入:
使用@import
语句可以导入外联样式表,@import后跟需要导入的外联样式表的相对路径,用;表示语句结束。示例代码如下:
/** common.wxss **/
.small-p {
padding:5px;
}
/** app.wxss **/
@import "common.wxss";
.middle-p {
padding:15px;
}
微信官方文档请参考
第七节:flex布局
flex布局是继标准流布局、浮动布局、定位布局后的第四种布局方式。这种方式可以非常优雅的实现子元素居中或均匀分布,甚至可以随着窗口缩放自动适应。flex布局在浏览器中存在一定的兼容性。
具体参考
但是在小程序中,是完全兼容flex布局的,并且微信官方也是推荐使用flex布局的。下面就来详细的讲下flex布局。
案例:
- 代码:
<view class='outter'>
<view class='inner'>1</view>
<view class='inner'>2</view>
</view>
.outter{
display: flex;
justify-content: space-between;
width: 300px;
height: 200px;
background: pink;
}
.outter .inner{
background: gray;
width: 100px;
height: 100px;
}
- 最后的效果图:
基本概念:
- **弹性容器:**包含着弹性项目的父元素。通过设置
display
属性的值为flex
或inline-flex
来定义弹性容器。 - **弹性项目(Flex item):**弹性容器的每个子元素都称为弹性项目。弹性容器直接包含的文本将被包覆成匿名弹性项目。也可以称为子容器。
- **轴(Axis):**每个弹性框布局包含两个轴。弹性项目沿其依次排列的那根轴称为主轴(
main axis
)。垂直于主轴的那根轴称为侧轴(cross axis
)。 - **方向(Direction):**可以通过
flex-direction
来确定主轴和侧轴的方向
设置在主轴上的排列方式:
默认情况下,主轴的方向是从左到右。在主轴方向上,可以通过justify-content
属性来设置他们的排列方式。排列方式有以下几种:
flex-start
:项目靠近父盒子的左侧。默认采用的就是这种排列方式。示例图如下:
flex-end
:项目靠近父盒子的右侧。
center
:所有项目会挨在一起在父盒子的中间位置。
space-around
:项目沿主轴均匀分布,位于首尾两端的子容器到父容器的距离是子容器间距的一半。
space-between
:项目沿主轴均匀分布,位于首尾两端的子容器与父容器紧紧挨着。
space-evenly
:项目在主轴上均匀分布,收尾两端的自容器到父容器的距离跟自容器间的间距是一样的。
设置在侧轴上的排列方式:
默认情况下,侧轴的方向是从上到下。在侧轴方向上,可以通过align-items
属性来设置他们的排列方式。排列方式有以下几种:
flex-start
:起始端对齐。默认就是这种对齐方式。
flex-end
:末尾段对齐。
center
:中间对齐。
stretch
:如果项目没有设置高度。那么子容器沿交叉轴方向的尺寸拉伸至与父容器一致。比如我们将.inner的高度属性去掉,代码如下:
.outter .inner{
background: gray;
width: 100px;
/* height: 100px; */
border: 1px solid #ccc;
}
效果图为:
5. baseline
:基线对齐,这里的 baseline 默认是指首行文字,所有子容器向基线对齐,交叉轴起点到元素基线距离最大的子容器将会与交叉轴起始端相切以确定基线。比如我们把代码改成如下:
<view class='outter'>
<view class='inner'>
<view style='margin-top:10px;background:#eee;'>hello</view>
</view>
<view class='inner'>2</view>
</view>
然后wxss文件为:
.outter{
display: flex;
align-items: baseline;
width: 300px;
height: 200px;
background: pink;
}
.outter .inner{...}
那么效果图为:
更换主轴和侧轴方向
主轴默认的方向是从左到右,侧轴的方向默认是从上到下,当然也可以进行修改。可以通过flex-direction
进行修改。可以修改的参数为以下:
row
:默认属性。从左到右。
row-reverse
:从右到左。
column
:从上到下。
column-reverse
:从下到上。
换行
默认情况下,元素个数如果超过一定数量,那么在一行当中就排列不下。此时flex
默认的处理方式是压缩元素,使其能在一行中排列下来。比如以下代码:
<view class='outter'>
<view class='inner'>1</view>
<view class='inner'>2</view>
<view class='inner'>3</view>
<view class='inner'>4</view>
</view>
.outter{
display: flex;
width: 300px;
height: 200px;
background: pink;
}
.outter .inner{
background: gray;
width: 100px;
height: 100px;
border: 1px solid #ccc;
}
那么会把这四个元素挤压在一行中。即使给元素设置了宽度也没有用的。效果图如下:
可以通过flex-wrap
来改变排列的方式。可以设置的属性如下:
nowrap
:不换行。默认的。
wrap
:换行。
wrap-reverse
:换行,但是第一行会在下面。
align-content属性
在排列中,如果有多行,那么这个属性是设置多行之间的排列方式。可以通过align-content
属性来确定排列的方式。可以设置以下值。
flex-start
:从上往下排列。示例代码如下:
.outter{
display: flex;
flex-wrap: wrap;
align-content: flex-start;
width: 300px;
height: 300px;
background: pink;
}
flex-end
:末尾段对齐。效果图如下:
center
:中点对齐。效果图如下:
space-between
:与交叉轴两端对齐,轴线之间的间隔平均分布。效果图如下:
space-around
:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。效果图如下:
stretch
:默认方式,如果没有给元素设置高度,那么会占满整个交叉轴。
.outter .inner{
background: gray;
width: 100px;
/* height: 100px; */
border: 1px solid #ccc;
box-sizing: border-box;
}
效果图如下:
元素(子容器)的相关属性
flex-basis:
定义了在分配多余空间之前,项目占据的主轴空间,浏览器根据这个属性,计算主轴是否有多余空间。
.item {
flex-basis: <length> | auto;
}
默认值:auto
,即项目本来的大小, 这时候 item
的宽高取决于 width
或 height
的值。
当主轴为水平方向的时候,当设置了 flex-basis
,项目的宽度设置值会失效,flex-basis
需要跟 flex-grow
和 flex-shrink
配合使用才能发挥效果。
当 flex-basis
值为 0
时,是把该项目视为零尺寸的,故即使声明该尺寸为 140px
,也并没有什么用。
当 flex-basis
值为 auto
时,则跟根据尺寸的设定值(假如为 100px
),则这 100px
不会纳入剩余空间。
flex-grow:
设置元素是否需要扩大的比例。默认值为0
,即如果存在剩余空间,也不放大。比如有以下代码:
<view class='outter'>
<view class='inner inner1'>1</view>
<view class='inner inner2'>2</view>
</view>
wxss代码为:
.outter{
display: flex;
width: 300px;
height: 300px;
flex-wrap: wrap;
background: pink;
}
.outter .inner{
background: gray;
width: 100px;
height: 100px;
border: 1px solid #ccc;
box-sizing: border-box;
}
.outter .inner1{
flex-grow: 2;
}
.outter .inner2{
flex-grow: 1;
}
效果图为:
因为两个元素分别占了2份,1份,所以第一个元素是占据了整个容器宽度的2/3,第二个元素占据了整个容器宽度的1/3。
另外,如果设置flex-grow
为0
,那么他的宽度将会保持为设置的宽度,如果宽度没有设置,那么将根据他的子元素来保留宽度。假如代码为:
<view class="outter">
<view class="inner inner1">1</view>
<view class="inner inner2">2</view>
</view>
wxss代码为:
.outter .inner1{
flex-grow: 0;
}
.outter .inner2{
flex-grow: 1;
}
效果图为:
如果把inner1
的width
删掉,那么效果图为:
flex-shrink属性:
定义了项目的缩小比例,默认为1
,即如果空间不足,该项目将缩小。比如有以下代码:
<view class="outter">
<view class="inner inner1">1</view>
<view class="inner inner2">2</view>
<view class="inner">3</view>
<view class="inner">4</view>
</view>
wxss的代码如下:
.outter{
display: flex;
width: 300px;
height: 300px;
background: pink;
}
.outter .inner{
background: gray;
width: 100px;
height: 100px;
border: 1px solid #ccc;
box-sizing: border-box;
}
.outter .inner2{
flex-shrink: 0;
}
效果图为:
因为给inner2
设置了flex-shrink
为0
,所以即使在空间不够的情况下,他也不会被压缩。
flex属性:
flex属性是flex-grow
flex-shrink
flex-basis
三个属性的简写。假设以上三个属性同样取默认值,则 flex
的默认值是0 1 auto
。
关于flex
的取值,有以下几种方式:
auto
:等价于1 1 auto
。也就是允许增长,允许缩小,宽度为自动。none
:等价于0 0 auto
。也就是不允许增长,不允许缩小,宽度为自动。- 非负数字:这个数字表示的是
flex-grow
的值,flex-shrink
为1
,表示允许缩小,flex-basis
为0%
。可以认为他就是把剩余的空间进行填充。比如以下代码是等价的:
.item {
flex: 1;
}
.item {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0%;
}
0
:对应的三个值分别为0 1 0%
。比如以下代码是等价的:
.item {flex: 0;}
.item {
flex-grow: 0;
flex-shrink: 1;
flex-basis: 0%;
}
- 长度或者百分比:则这个值视为
flex-basis
的值,而flex-grow
为1
,flex-shrink
为1
。比如以下代码是等价的:
.item-1 {flex: 0%;}
.item-1 {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0%;
}
.item-2 {flex: 24px;}
.item-2 {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 24px;
}
- 两个非负数字:分别视为
flex-grow
和flex-shrink
的值,flex-basis
取0%
,如下是等同的:
.item {flex: 2 3;}
.item {
flex-grow: 2;
flex-shrink: 3;
flex-basis: 0%;
}
- 一个非负数字和一个长度或百分比:则分别视为
flex-grow
和flex-basis
的值,flex-shrink
取1
,如下是等同的:
.item {flex: 11 32px;}
.item {
flex-grow: 11;
flex-shrink: 1;
flex-basis: 32px;
}
更多关于flex布局请参考:
mozilla
zhihu
第八节:APP对象
请参考
onLaunch(options):
-
调用时机:小程序被加载完毕的时候调用。这个方法一般用来做一些初始化的事情。比如获取用户信息、获取历史缓存信息、获取小程序打开来源等。
-
参数:
参数 | 类型 | 说明 |
---|---|---|
path | String | 打开小程序的路径 |
query | Object | 打开小程序的query |
scene | Number | 打开小程序的场景值 |
shareTicket | String | shareTicket,详见 获取更多转发信息 |
referrerInfo | Object | 当场景为由从另一个小程序或公众号或App打开时,返回此字段 |
referrerInfo.appId | String | 来源小程序或公众号或App的 appId,详见下方说明 |
referrerInfo.extraData | Object | 来源小程序传过来的数据,scene=1037或1038时支持 |
onShow(options):
- 调用时机:小程序启动,或从后台进入前台显示时调用。如果想要在小程序每次进入到前台的时候都执行一些事情,那么可以把代码放在这个里面。比如一些实时动态更改的数据,用户每次进来都要从服务器更新,那么我们就可以在这个里面做。
- 参数:同onLoad。
onHide():
- 调用时机:小程序被切换到后台(包括微信自身被切换到后台或者小程序暂时被切换到后台时)。可以在这个方法中做一些数据的保存。
- 参数:无。
onError(String error):
- 调用时机:小程序发生脚本错误,或者 api 调用失败时触发。在小程序发生错误的时候,会把错误信息发送到这个函数中,所以可以在这个函数中做一些错误收集。
- 参数:error。
onPageNotFound(Object):[有bug]
- 调用时机:小程序要打开的页面不存在时触发。一般在代码更新的时候,有些页面被删除了,但是其他地方没有改过来的情况下会发生这种情况,或者一些活动页面,活动结束后被关掉了。也可以在这个里面做一些错误的收集和页面的重新跳转。
- 参数:
字段 | 类型 | 说明 |
---|---|---|
path | String | 不存在页面的路径 |
query | Object | 打开不存在页面的 query |
isEntryPage | Boolean | 是否本次启动的首个页面(例如从分享等入口进来,首个页面是开发者配置的分享页面) |
- 开发者可以在 onPageNotFound 回调中进行重定向处理,但必须在回调中同步处理,异步处理(例如 setTimeout 异步执行)无效。示例代码:
App({
onPageNotFound(res) {
wx.redirectTo({
url: 'pages/...'
}) // 如果是 tabbar 页面,请使用 wx.switchTab
}
})
- 注意:如果开发者没有添加 onPageNotFound 监听,当跳转页面不存在时,将推入微信客户端原生的页面不存在提示页面。 如果 onPageNotFound 回调中又重定向到另一个不存在的页面,将推入微信客户端原生的页面不存在提示页面,并且不再回调 onPageNotFound。
getApp():
获取当前的app对象。一般在其他的page页面中调用。有以下两个注意点:
- 不要在定义于 App() 内的函数中调用 getApp() ,使用 this 就可以拿到 app 实例。
- 通过 getApp() 获取实例之后,不要私自调用生命周期函数。
第九节:Page对象
详情请参考
Page对象作用:
Page(Object)
函数用来注册一个页面。接受一个 Object 类型参数,其指定页面的初始数据、生命周期回调、事件处理函数等。
数据渲染:
需要放在模板中进行渲染的数据,需要放在Page
对象的data
属性中。示例代码如下:
Page({
data: {
person: {
username: "知了课堂",
age: 18
},
books:[
"西游记",
"西游记",
"西游记",
"西游记"
]
}
})
<view>
{{person.username}}
</view>
<view wx:for="{{books}}">
{{item}}
</view>
修改数据:
page({
onLoad:function(options){
// 注意: 下面注掉的方式 修改不了data中的值,会出现错误
// tis.data.username = 'python学院'
// 1. 正确的修改方案
var person = this.data.person;
person.username = 'python学院';
this.setData({
person: person
})
// 2. 或
this.setData({
"person.username": 'python学院'
})
// 3. 数组:如果添加数组数据还是第一种比较好
this.setData({
"books[3]": '三国演义'
})
},
})
- 如果以后想要修改
data
中的值,应该使用setData
方法。setData
函数用于将数据从逻辑层发送到视图层(异步),同时改变对应的this.data
的值(同步)。注意事项:
- 直接修改
this.data
而不调用this.setData
是无法改变页面的状态的,还会造成数据不一致。 - 放到
data
中的值,只能使用可以JSON序列化的:字符串,数字,布尔值,对象,数组。否则将不会渲染。 - 其中key可以以数据路径的形式给出,支持改变数组中的某一项或对象的某个属性,如
array[2].message
,a.b.c.d,并且不需要在this.data
中预先定义。
Page生命周期函数:
onLoad(Object query):
页面加载时触发。一个页面只会调用一次,可以在 onLoad
的参数中获取打开当前页面路径中的参数。一般建议在这个函数中做一些页面的数据初始化工作。
onShow():
页面显示/切入前台时触发。比如新推入了一个新的页面,那么原来的页面就处于后台,这时候如果把新页面又移除掉,那么下面的页面就会调用onShow
方法。
onReady():
页面初次渲染完成时触发。一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互了。对界面内容进行设置的 API 如wx.setNavigationBarTitleText
,比较合适在这个里面执行。
onHide()
页面隐藏/****切入后台时触发。如navigateTo
或底部tab切换到其他页面,小程序切入后台等。
onUnload()
页面卸载时触发。如redirectTo
或navigateBack
到其他页面时。
路由:
在小程序中所有页面的路由全部由框架进行管理。getCurrentPages()
可以获取当前状态下的页面栈。
第十节:WXS语法
在传统的网页开发中,HTML
中是可以写JavaScript
代码的,而在小程序中,是不允许在WXML
文件中写JavaScript
的,但是有些时候,我们需要在wxml
中实现一些逻辑的处理。比如举个例子,我们渲染一个数字到wxml
中,在wxml文件中根据这个数字来渲染具体星期几。这时候通过wxml
文件中就做不了了,或者只能在JavaScript
先计算好再渲染。示例代码如下:
<view>{{weekday}}</view>
Page({
data: {
day: 1
},
onLoad: function (options) {
var weekday = "";
switch(this.data.day){
case 1:
weekday = "星期一";
break;
case 2:
weekday = "星期二";
break;
case 3:
weekday = "星期三";
break;
case 4:
weekday = "星期四";
break;
case 5:
weekday = "星期五";
break;
case 6:
weekday = "星期六";
break;
case 7:
weekday = "星期天";
break;
}
this.setData({
weekday: weekday
});
}
});
这时候小程序就提供了一个新的语法叫做wxs
可以帮我们直接在wxml
中解决。示例代码如下:
<wxs module="index">
var getWeekDay = function(day){
var weekday = "";
switch(day){
case 1:
weekday = "星期一";
break;
case 2:
weekday = "星期二";
break;
case 3:
weekday = "星期三";
break;
case 4:
weekday = "星期四";
break;
case 5:
weekday = "星期五";
break;
case 6:
weekday = "星期六";
break;
case 7:
weekday = "星期天";
break;
}
return weekday;
}
module.exports.getWeekDay = getWeekDay;
</wxs>
<view>{{index.getWeekDay(day)}}</view>
wxs
可以理解为javascript
的一个阉割版本。使用wxs
的好处如下:
- 在iOS上,在wxs中代码执行效率是在js中执行的2-20倍。
- 可以把更多的逻辑在wxml文件中完成。
wxs代码:
wxs
代码可以写在wxml
文件中。也可以单独放在.wxs
后缀的文件中。如果是写在wxml
文件中,则必须要放在wxs
标签中,如果是单独放在.wxs
后缀文件中,就不需要放在wxs
标签中了。并且必须要给wxs
一个module
属性,用来标记这个wxs
的名称。以下是使用.wxs
的语法。
// /pages/tools.wxs文件
<wxs module="tools">
var person = {
"username": "zhiliao",
"age": 18
}
module.exports = person;
</wxs>
以后想使用的时候,就直接在wxml代码中使用wxs来引用wxs文件。示例代码如下:
<wxs src="./../tools.wxs" module="tools">
<view> {{tools.username}} </view>
</wxs>
另外,我们在wxs
中写完了代码,还需要导出才能够使用。使用module.exports
即可导出。
require函数:
如果在一个wxs
文件中,想引用另外一个wxs
文件,那么可以使用require
函数引用。示例代码如下:
// tools.wxs
var person = {
"username": "zhiliao",
"age": 18
}
module.exports.person = person;
在另外一个wxs
文件中就可以进行引用了。示例代码如下:
var tools = require("./tools.wxs");
console.log(tools.person.username);
变量:
变量的定义跟javascript
一致。请查看
注释:
注释使用/*注释*/
以及//注释
的方式,另外增加了一种/* xxx
的方式,这种方式会把/*
后的所有代码全部都注释了。
运算符:
yu
你算符跟javascript
一致。请查看
语句:
包括有if
语句、for
循环语句、while
循环语句、switch
分支语句。具体查看
数据类型:
number : 数值
string :字符串
boolean:布尔值
object:对象
function:函数
array : 数组
date:日期
regexp:正则
其中每种数据类型的方法请参考
内置类库:
wxs
提供了一些内置的类库,方便开发者调用。具体请看
wxs案例:
根据时间,来显示距离现在的时间间隔。
1.如果时间间隔小于1分钟以内,那么就显示“刚刚”
2.如果是大于1分钟小于1小时,那么就显示“xx分钟前”
3.如果是大于1小时小于24小时,那么就显示“xx小时前”
4.如果是大于24小时小于30天以内,那么就显示“xx天前”
5.否则就是显示具体的时间2017/10/20 16:15。
版权声明:本文标题:wx小程序笔记(1) 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dongtai/1725736940a1039835.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论