项目结构:
创建完一个新的项目后。会出现以下的目录结构:
- 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 语法,并且增加了导入的功能。所以如果你
对前端比较熟悉,学习微信小程序开发就非常简单了。
WXML语法:
微信官方教程如下:https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/
特点:
- 布局的方式跟HTML是一模一样的。
- 标签的名字不再是传统的HTML的了,而是使用微信自己定义的一套,所以写代码的时候完全使用之前写
HTML的方式去写,只不过改个标签名就可以了。 - WXML的语法,和一些模板语法比如Django中的模板语法非常的类似。
变量渲染:
- 使用双大花括号。
- 获取对象的值,通过下标获取数组中的值。
- 可以做运算,比如判断,四则运算等。
- 总而言之一句话:需要使用js中传过来的值,就必须使用双大花括号。
条件渲染:
- 在指定的标签中使用 wx:if="条件" ,如果条件成立,则会渲染这个标签。示例代码如下:
<view wx:if="{{age > 18}}">
进入网吧
</view>
- else 和 elif 可以直接在 if 下面使用。示例代码如下:
<view wx:if="{{weather == '晴天'}}">
出去旅游
</view>
<view wx:elif="{{weather == '阴天'}}">
去逛街
</view>
<view wx:else>
哪里都不去
</view>
注意:elif和else只能跟在if后面,否则会报错
- 如果需要通过条件来判断是否需要渲染一组标签,那么可以使用 block 。示例代码如下:
<block wx:if="{{weather == '晴天'}}">
<view>
出去旅游
</view>
</block>
<block wx:elif="{{weather == '阴天'}}">
<view>
去逛街
16
</view>
</block>
<block wx:else>
<view>
哪里都不去
</view>
</block>
列表渲染:
- 通过语法 wx:for="{{列表}}" 来渲染一个列表。示例代码如下:
<view wx:for="{{[1,2,3,4]}}">
{{item}}
</view>
- 循环中,默认的下标名称是 index ,默认的值的名称是 item 。如果想要修改循环列表的值和下标的名称,那
么可以通过 wx:for-index 和 wx:for-item 来指定。示例代码如下:
<view wx:for="{{[1,2,3,4]}}" wx:for-index='idx' wx:for-item="value">
{{index}}/{{value}}
</view>
- 如果想要在循环中渲染多个标签,那么也可以通过 block 来实现。示例代码如下:
<block wx:for="{{[1,2,3,4]}}">
<view>{{index}}</view>
<view>{{item}}</view>
九九乘法表案例:
image.pngwxml文件代码:
<view wx:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-index="index1" wx:for-item="row" class='row'>
<view wx:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-index="index2" wx:for-item="col" wx:if="{{col <= row}}" cla
ss='col'>
{{col}}*{{row}}={{row*col}}
</view>
</view>
wxssw文件代码:
.row{
display: flex;
justify-content: start;
font-size: 10px;
}
.row .col{
width: 40px;
}
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, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。
模板:
有些时候,一段布局代码我们需要在多个地方使用,那么我们可以将其定义成模板,然后把变量单独抽取出来,通
过调用模板的时候再传递过去。示例代码如下:
<template name="msgItem">
<view>
<text> {{index}}: {{msg}} </text>
<text> Time: {{time}} </text>
</view>
</template>
调用模板:
<import src="../../templates/msgItem.wxml" />
<template is="msgItem" data="{{index:1,msg:"你好!",time:3000年10月22日}}"/>
在传递变量的时候第三节:WXML语法,如果是直接从js文件中获取到的,那么可以通过 ...item 的方式来展开显
示。示例代码如下:
Page({
data: {
message: {
index: 1,
msg: '你好!我是知了课堂!',
time: '2018年10月22日'
}
}
});
<import src="../../templates/msgItem.wxml" />
<template is="msgItem" data="{{...message}}"/>
另外,如果想使用模板的样式文件,也需要在 wxss 文件中导入模板的 wxss 文件。示例代码如下:
@import "../../../templates/msgItem.wxss";
include:
如果一段代码是不需要填入动态的数据,那么可以直接使用 include 把这段代码引入到其他的地方。示例代码如
下:
header.html中的代码:
<view>
这是header.wxml中的内容
</view>
index.wxml中的代码:
<include src="header.wxml" />
<view>
这里是index.wxml中的代码
</view>
事件
绑定事件:
在组件上使用 bind:事件名称="执行的函数" 即可绑定事件。然后可以在 js 文件中,实现具体的 执行的函数 。以后在这个
组件上发生了 bind 后的事件,那么就会触发 js 中的函数了。示例代码如下:
<view bind:tap='onViewClick'>
点击我
</view>
在js代码中:
Page({
// 前面的代码
onViewClick: function(event){
console.log('view被点击了!');
}
});
获取元素上的数据:
我们能捕获到点击事件还不够,我们在点击的时候还要获取一些数据。比如文章列表,我点击了某个文章列表的容
器,我想获取这个容器的对应的文章,那么就需要把这个文章的id绑定到 view 上面,以后我在点击的时候,这个
数据再通过 event 参数传递给后台的 js 函数。绑定数据的时候,我们需要通过 data-数据名 的方式绑定。示例代码
如下:
<view wx:for="" data-id="" bind:tap='onArticleClick'>
</view>
js 代码如下:
Page({
onArticleClick: function(event){
console.log(event);
}
});
事件冒泡和事件捕获:
绝大部分小程序定义好的事件都是冒泡的。冒泡是什么意思呢,就是点击一个子元素,如果事件是冒泡的,那么这
个事件也会传递给父元素。如在下边这个例子中,点击 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 。
网友评论