三、逻辑层
1.概念
1.小程序开发框架的逻辑层使用 JavaScript
引擎为小程序提供开发者 JavaScript
代码的运行环境以及微信小程序的特有功能。
2.逻辑层将数据进行处理后发送给视图层,同时接受视图层的事件反馈。
3.小程序其他逻辑层功能:
- 增加
App
和Page
方法,进行程序注册和页面注册。 - 增加
getApp
和getCurrentPages
方法,分别用来获取App
实例和当前页面栈。 - 提供丰富的 API,如微信用户数据,扫一扫,支付等微信特有能力。
- 提供模块化能力,每个页面有独立的作用域。
注意:小程序运行的环境不是浏览器,没有windows也没有document
2.注册小程值app.js
每个小程序都需要在 app.js
中调用 App
方法(构造函数)注册小程序实例,绑定生命周期回调函数、错误监听和页面不存在监听函数等。
https://developers.weixin.qq.com/miniprogram/dev/reference/api/App.html
App() 必须在 app.js
中调用,必须调用且只能调用一次。不然会出现无法预期的后果。
App({
//全局注册小程序唯一实例
/**
* 当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
*/
onLaunch() {
console.log('整个周期内只执行一次')
},
/**
* 当小程序启动,或从后台进入前台显示,会触发 onShow
*/
onShow: function (options) {
console.log('小程序初始化完毕后,小程序才显示出来')
},
/**
* 当小程序从前台进入后台,会触发 onHide
*/
onHide: function () {
console.log('小程序隐藏了,')
},
/**
* 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息
*/
onError: function (msg) {
console.log(msg,'监听全局的错误')
}
})
//页面不存在监听函数
onPageNotFound(){
// 有二维码
console.log('数据不存在')
wx.redirectTo({
url: '/pages/index/index',
})
}
可以任意js中的数据类型。但是经常定义成一个对象
在其他页面,可以访问到全局的小程序唯一实例对象。当然在app.js中引入可任意访问(使用较少)
data123:{
name:20,
hobby:['白骨精','嫦娥姐姐']
}
生命周期完全可以称作为事件函数
getApp和setApp
getApp()返回小程序的唯一实例对象
let objApp= getApp()
console.log(objApp,'我是在index页面访问的App实例')
3.注册页面Page()
注册页面实例
定义页面生命周期、事件函数、自定义函数、页面中的私有数据。同时Page方法也必须穿一个参数
Page({
data:{//私有数据,但是访问到页面实例,也能访问到data,同时,视图层也能访问到。
name:'孙悟空'
age:500
},
fn1(){
//事件函数,普普通通的函数
console.log('我是fn1函数')
console.log(this.data.name)
},
//Page->注册页面实例
onLoad(){
// 页面创建时执行
console.log(this)//this->Page的对象实例
console.log(this.data.name)//
this.fn1();
},
onShow(){
//页面出现在前台时执行
},
onHide(){
// 页面从前台变为后台时执行
},
onReady(){
//页面首次渲染完毕后执行
},
onPullDownRefresh(){
enablePullDownRefresh app.json page.json
//下来刷新功能
},
onReachBottom(){//距离底部距离
onReachBottomDistance app.json page.json 默认距离50px触发
//加载更多,下一页功能
},
onPageScroll(){//onscroll
//可以实时监听用户滚动并获取滚动距离,用户滚动页面就会触发
}
})
index.wxml中渲染数据
{{name}}
**getCurrentPages()**获取页面栈信息
index.js
let pages = getCurrentPages()
4.生命周期
App的生命周期
页面的生命周期
初始化到显示:
先执行app中的onLaunch->onShow->然后再执行页面的onLoad->onShow->onReady()
隐藏:
先执行页面的onHide再执行app的onHide
四、视图层
框架的视图层由 WXML 与 WXSS 编写,由组件来进行展示。
将逻辑层的数据反应成视图,同时将视图层的事件发送给逻辑层。
WXML(WeiXin Markup language) 用于描述页面的结构。
WXS(WeiXin Script) 是小程序的一套脚本语言,结合 WXML
,可以构建出页面的结构。
WXSS(WeiXin Style Sheet) 用于描述页面的样式。
组件(Component)是视图的基本组成单元。
1.wxml语法
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/
标签(组件):文字内容、组件名、属性(属性值)、事件
1.数据绑定
数据绑定使用 Mustache 语法(双大括号)将变量包起来
总结:无论是绑定到属性上还是标签内部,都需要放变量放到双大括号中
Number\String\Boolean\Object\Array
Function在小程序中只能是事件函数,要么在逻辑层中主动调用
index.js
Page({
data:{
name:'swk',
age:500,
isPerson:false,
idx:box123,
hobby:['吃苹果','香蕉'],
person:{
name:'tsz',
job:'取经'
}
},
fn1(){
},
clickHandle(){
console.log('ok');
//改变data借鉴了react
this,setData({
age:50
})
}
})
index.wxml
1.基本数据渲染
<view>{{name}}</view>
2.属性绑定:建议放到双引号内
<view class="abcd">我是一个view容器</view>
<view id="{{idx}}">我是一个view容器</view>
<view bindatp="clickHandle">点击我</view>
3.控制属性
如果不写属性值,默认值为true
true/false必须加双引号,非空字符串都理解为真值
控制属性:hidden checked是否选中
<checkbox checked="{{true}}"></checkbox>
<checkbox checked="{{flase}}"></checkbox>
<checkbox checked></checkbox>
关于运算
支持简单的运算
算术、字符串拼接、三目运算、路径运算(访问数组、访问对象)、逻辑判断
不支持调用函数(vue支持)
4.关于一些基本运算
<view>{{1+1}}</view>
<view>{{'abc'+name}}</view>
<view>{{age+20}}</view>
<view>{{isPerson?'是个人':'是个猴'}}}</view>
<view>{{person.name+person.job}}</view>
<view>{{hobby[1]}}</view>
<view>{{fn1()}}</view>//不支持这种语法
2.列表渲染
属性的指令:for、当前项、当前下标、唯一的key属性
wx:for
wx:for-item
wx:for-index
wx:for
Page({
data:{
nums:[11,22,33,44],
item:'我是页面的item值',
index:'我是页面的index',
person:{
name:'猪八戒',
age:20
},
products:[
{
id:'10001',
name:'小米',
price:12000
},
{
id:'10002',
name:'华为',
price:7000
},
{
id:'10003',
name:'苹果',
price:1000
}
],
str:'qaz'
}
})
1.基本的遍历
wx:for="{{变量}}"
默认当前值的变量为item,下标为index
<view wx:for="{{nums}}">
当前值为{{item}}-----当前下标为:{{index}}
</view>
2.改变item和index
<view wx:for="{{nums}}" wx:for-item="val" wx:for-index="idx">
当前值为{{val}}-----当前下标为:{{idx}}
</view>
3.渲染对象
<view wx:for="{{person}}" wx-for-index="key">
{{item}}:{{key}}
</view>
4.数组套对象
<view wx:for="{{products}}">
{{iyem.id}}---{{item.name}}---{{item.price}}
</view>
5.渲染多维数组 九九乘法表
建议重新定义index和item
<view wx:for="{{1,2,3,4,5,6,7,8,9}}" class="father" wx:for-item="i">
<view wx:for="{{1,2,3,4,5,6,7,8,9}}" class="son" wx:for=item="j">
<view wx:if="{{i<=j}}">{{i}} * {{j}} = {{i*j}}</view>
</view>
</view>
循环的注意事项
1.block不会产代码,是代码的搬运工
<block wx:for="{{products}}">
<view>{{item.name}}</view>
</block>
2.关于渲染时空格的问题
数组变量的花括号外面千万不要加空格
<view wx:for="{{products}} ">
<view>{{item.name}}</view>
</view>
3.遍历字符串
<view wx:for="{{str}} ">
<view>{{item}}</view>
</view>
<view wx:for="{{[11,22]+'abc'}} ">//变成字符串
<view>{{item}}</view>
</view>
4.列表渲染指key属性
<!-- 基本遍历 -->
<!--
wx:key属性,指定每一次循环中(当前项的唯一性)
两种方式:
*this 当前循环项的值,item需为本身是一个唯一的字符串或数组不能对对象
字符串,item中某个property,唯一性,不能动态改变
-->
<view wx:for="{{num}}" wx:key="*this">
{{item}}
</view>
<view>--------</view>
<view wx:for="{{products}}" wx:key="id">
{{item}}
</view>
<view wx:for="{{prodycts}}" wx:key="index">
{{item.name}}
</view>
3.条件渲染
<!-- 1.基本的条件渲染 -->
<!--
wx:if
wx:elif
wx:else
-->
<view wx:if="{{!isPerson}}">这是一个二哈</view>
<view wx:else>我是一个猫星人</view>
<!-- 多分支 -->
<view wx:if="{{score>=90}}">hehe</view>
<view wx:elif="{{score>=80&&score<90}}">还可以</view>
<view wx:else>你要上天啊</view>
<view>---------</view>
<!-- block:if -->
<block wx:if="{{true}}">
<view>猪八戒</view>
<view>背媳妇</view>
</block>
<!-- wx:iif VS hidden -->
<!--
如果是在页面中频繁切换,则使用hidden
如果页面在初始完毕后,某个要么显示要么隐藏,不会频繁切换,则使用if
-->
<!--
在购物车中可以使用wx:if
-->
<block wx:if="{{cartList.length>0}}">
<view wx:for="{{cartList}}">
{{item.name}}
</view>
</block>
<view wx:else>购物车为空</view>
<!--
hidden 是否隐藏 做选项卡切换
checked
-->
<view hidden="{{false}}">我隐藏吗-能看见</view>
<view hidden="{{true}}">我隐藏吗-不能看见</view>
4.模板
能够解决代码复用,但是代码复用,有很多种方式,不仅有这一种方式是小程序特有,借鉴后端知识(include)
模块化、组件化
1.模板的基本使用
<!--
模板的使用
1.定义模板:模子
<template name="模板名称">
书写具体的结构
</template>
2.使用
<template is="模板名称"></template>
<template is="模板名称"/>自闭和
-->
<!-- 定义模板 -->
<template name="tmp1">
<view>我是tmp1模板</view>
<view>当然,使用模板,也可以往内部传递数据</view>
</template>
<!-- 使用模板 -->
<template is="tmp1"></template>
<template is="tmp1"/>
2.模板中传递数据
<!--
定义模板
使用模板往模板中传递数据,必须使用data属性
-->
<template name="tmp2">
<view>我是tmp2模板</view>
<view>{{name}}--{{age}}</view>
</template>
<template is="tmp2" data="{{name:'zbj',age:30}}"></template>
<template is="tmp2" data="{{...person}}"></template>
<!-- ...对象前,展开运算符 -->
5.引用
<!--
引用:
<import/>小程序特有的,引入的除普通代码外的模板代码,template内的代码
<include/>引入出template外的代码
尽量不要混用
-->
<!-- 注意:wxml文件需要带后缀 -->
<import src="../public/header.wxml" />
<import src="../public/footer.wxml" />
<template is="header"></template>
<template is="footer"></template>
<!-- include解决了import的短板 -->
<include src="../public/header.wxml"/>
import的作用域
import 有作用域的概念,即只会 import 目标文件中定义的 template,而不会 import 目标文件 import 的 template。
如:C import B,B import A,在C中可以使用B定义的template
,在B中可以使用A定义的template
,但是C不能使用A定义的template
。
2.wxss样式
小程当中的适配问题,已经帮开发者解决好了,新的适配单位(rpx)
rpx(responsive pixel): 可以根据屏幕宽度进行自适应。**规定屏幕宽为750rpx。**如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。
开发微信小程序时设计师可以用 iPhone6 作为视觉稿的标准。
以下了解
样式导入,行内样式,选择器,全局样式,局部样式
/* 1.公共样式的导入方式一 */
@import '../public/header.wxss';
公共样式,其他文件自动加载,无需手动引入:app.wxss
局部样式如果和全局样式冲突,看优先级。
id>class>标签
权重一样,就近原则
3.事件相关
绑定、事件函数、如何传参、事件对象
- 事件是视图层到逻辑层的通讯方式。
- 事件可以将用户的行为反馈到逻辑层进行处理。
- 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。
- 事件对象可以携带额外信息,如 id, dataset, touches。
1.基本使用
<!-- 1.事件基本的使用 -->
<!--
bind+事件名="函数名称"
绑定事件函数,大部分情况是不应该绑定箭头函数的
-->
<view class="box" bindtap="handleFn1">fn1</view>
<view class="box" bindtap="handleFn2">fn2</view>
<view class="box" bindtap="handleFn3">fn3</view>
js
Page({
data:{
},
handleFn1(){//ES6中函数的简写形式
console.log('fn1',this);
},
handleFn2:function(){//函数声明
console.log('fn2',this)
},
handleFn3: ()=> {//箭头形式,访问不到this
console.log('fn3',this)
}
})
2.有关箭头之this说明
handleFn4() {
let arr = [11,22,33]
let newArr = arr.map(item=>{
return item+this.data.jiaxin;
})
console.log(newArr);
}
handleFn4() {
let arr = [11, 22, 33]
let that = this;
let newArr = arr.map(function(item){
return item + that.data.jiaxin;
})
console.log(newArr);
}
3.事件分类
冒泡:当一个组件上的事件被触发后,该事件会向父节点传递。
非冒泡:当一个组件上的事件被触发后,该事件不会向父节点传递。
4.绑定事件分类
bind+事件名:不阻止冒泡
bind:事件名 不建议,意义不变
catch+事件名:阻止冒泡
catch:事件名 不建议,意义不变
<view class="outer box1" bindtap="outerHandle">
<view class="center box1" bindtap="centerHandle">
<view class="inner box1" bindtap="innerHandle"></view>
</view>
</view>
js
outerHandle() {
console.log('out')
},
centerHandle() {
console.log('center')
},
innerHandle() {
console.log('inner')
}
5.事件对象
1.开发者主动传递参数(通过事件对象)
<!-- 事件对象 -->
<!--
1.开发者主动传参。通过data-*-*去传递
data-name
data-password
data-user-name ->小驼峰:userName
-->
<view class="box" bindtap="changeThing" data-color="red" data-user-name="zbj"></view>
js
changeThing(e){
let {color,userName} = e.target.dataset;
console.log(color)
this.setData({
color
})
}
事件对象中
target:
dataset:
color: "red"
userName: "zbj"
2.detail
自定义事件所携带的数据,如表单组件的提交事件会携带用户的输入,媒体的错误事件会携带错误信息,详见组件定义中各个事件的定义。
点击事件的detail
带有的 x, y 同 pageX, pageY 代表距离文档左上角的距离。
2.事件发生后,会携带一些额外的数据信息(e.detail)
不同的标签会有不同的额外数据信息
3.target和currentTatget的区别
事件函数绑定在哪个组件上,data-就绑定在哪个组件上,通过currentTarget去获取
target是事件源
currentTarget当前事件绑定在哪个组件上
4.组件基础
内置组件
以后在小程序中,标签都统称为组件
什么是组件
- 组件是视图层的基本组成单元。
- 组件自带一些功能与微信风格一致的样式。
- 一个组件通常包括
开始标签
和结束标签
,属性
用来修饰这个组件,内容
在两个标签之内。
所有组件与属性都是小写,以连字符-
连接
1.属性类型
H5开发中,属性值只能是字符串
wx:for="array|object|string"
bindtap="function"
wx:if="boolean"
2.公共属性
所有组件上都有以下属性
属性名 类型 描述 注解
id String 组件的唯一标示 保持整个页面唯一
class String 组件的样式类 在对应的 WXSS 中定义的样式类
style String 组件的内联样式 可以动态设置的内联样式
hidden Boolean 组件是否显示 所有组件默认显示
data-* Any 自定义属性 组件上触发的事件时,会发送给事件处理函数
bind* / catch* EventHandler 组件的事件 详见事件
如果添加一些组件没有的属性,则小程序不会编译此属性
3.私有属性
学习内置组件其实就是学习私有属性
5.内置组件
1.text
<!-- 1.text组件 -->
<!--
selectable 是否可选择文本
space 控制空格的问题
decode 是否解码
-->
<!-- <text>我是文本</text> -->
<text selectable="{{true}}">我是文本</text>
<view>----------------------</view>
<text space="nbsp">ancd wws hijdind</text>
2.icon
<!-- 2.icon组件 size默认23-->
<icon type="success" size="23" color="red"/>
3.rich-text富文本组件
<!-- 3.rich-text组件 -->
<!--
nodes:节点
string
object
-->
<!-- 无法正常显示 -->
<h1 style="background:red">111</h1>
<rich-text nodes="{{htmlStr}}"/>
<rich-text nodes="{{arrStr}}"/>
js
data: {
htmlStr:'<h1 style="background:red">222</h1>',
arrStr:[
{
name:'h2',
attrs:{
id:'box',
class:'box123',
style:'background:blue'
},
children:[
{
type:'text',
text:'我是h2标签'
}
]
}
]
},
4.视图容器组件
(1)view
div划分区块
<!--
1.view使用
hover-class:模拟交互效果,当hover-class=none时,没有点击效果
hover-start-time 按下多久出现点击
hover-stay-time 松开手指停留多久
hover-stop-propagation 阻塞冒泡
-->
<view class="btn" hover-class="btn-active">点击我</view>
<view class="btn" hover-class="btn-active" hover-start-time="2000" hover-stay-time="3000">点击我</view>
<view class="box1" hover-class="box-active" >
<view class="box2" hover-class="box-active" hover-stop-propagation></view>
</view>
.btn{
width: 300rpx;
height: 80rpx;
line-height: 80rpx;
border-radius: 80rpx;
text-align: center;
background: red;
color: white;
}
.btn-active{
opacity: .6;
}
.box1{
background: blue;
width: 200px;
height: 200px
}
.box2{
background: red;
width: 100px;
height: 100px;
}
.box-active{
opacity: .6;
}
(2)swiper与swiper-item
<!--
swiper与swiper-item
-->
<swiper class="swiper-focus" indicator-dots="{{showDots}}" indicator-color="rgba(255,0,0,.6)" indicator-active-color="#00f" autoplay circular>
<!-- 子元素必须是swiper-item,我们不要给swiper-item写任何样式 -->
<!-- image默认不是显示图片的真实大小
swiper默认宽是100%,高是150px
swiper-item封装的是100%的宽,100%的高,不能改变swiper-item的任何样式,只需要改变swiper就可以
-->
<!--
indicator-dots true|false 是否显示小圆点
indicator-color 圆点颜色
indicator-active-color 当前项圆点颜色
autoplay 是否自动切换
duration 滚动的时间间隔
circle 是否衔接
-->
<swiper-item>
<image src="/static/banners/1.jpg"></image>
</swiper-item>
<swiper-item>
<image src="/static/banners/2.jpg"></image>
</swiper-item>
<swiper-item>
<image src="/static/banners/3.jpg"></image>
</swiper-item>
</swiper>
封装swiper
<view class="focus-container">
<swiper class="s-ul" bindchange="changeColor" current="{{current}}">
<swiper-item class="s-li" wx:for="{{banners}}" wx:key="index">
<image src="/static/banners/{{item}}"></image>
</swiper-item>
</swiper>
<view class="dots">
<text wx:for="{{banners}}" wx:key="index" class="{{index==current?'active':''}}"></text>
</view>
</view>
(3)scroll-view
横向滚动
<!-- scroll-view组件 -->
<!-- 横向滚动:
为scroll-view的子元素设置display:inline-block
同时为scroll-view设置不换行
scroll-x 是否横向滚动
-->
<scroll-view class="scroll-x" scroll-x>
<view>1</view>
<view>2</view>
<view>3</view>
<view>4</view>
<view>5</view>
<view>6</view>
<view>7</view>
</scroll-view>
.scroll-x{
height: 200rpx;
white-space: nowrap;
}
.scroll-x view{
width: 300rpx;
height: 200rpx;
margin-right: 20rpx;
background-color: red;
display:inline-block;
}
纵向滚动
<!-- 纵向滚动 -->
<!-- scroll-view的高度必须设置
scroll-y属性控制是否纵向滚动
-->
<scroll-view class="scroll-y" scroll-y>
<view>1</view>
<view>2</view>
<view>3</view>
<view>4</view>
<view>5</view>
<view>6</view>
<view>7</view>
</scroll-view>
css
.scroll-y {
height: 600rpx;
}
.scroll-y view {
width: 300rpx;
height: 200rpx;
margin-bottom: 20rpx;
background-color: red;
}
京东类别案例:
<!--
scroll-into-view:属性值 为子元素的某一个id值
-->
<view class="category-container">
<scroll-view class="category-l" scroll-y>
<view bindtap="_jumpCate" data-cate-id="cate1">手机</view>
<view bindtap="_jumpCate" data-cate-id="cate2">电脑</view>
<view bindtap="_jumpCate" data-cate-id="cate3">家居</view>
<view bindtap="_jumpCate" data-cate-id="cate4">家居1</view>
<view bindtap="_jumpCate">家居1</view>
<view bindtap="_jumpCate">家居1</view>
<view bindtap="_jumpCate">家居1</view>
<view bindtap="_jumpCate">家居1</view>
<view bindtap="_jumpCate">家居1</view>
</scroll-view>
<scroll-view class="category-r" scroll-y scroll-into-view="{{cateId}}">
<view class="father" id="cate1">
<view>华为手机</view>
<view>小米</view>
<view>小米</view>
<view>小米</view>
<view>小米</view>
</view>
<view class="father" id="cate2">
<view>华为电脑</view>
<view>小米</view>
<view>小米</view>
<view>小米</view>
<view>小米</view>
</view>
<view class="father" id="cate3">
<view>华为家居</view>
<view>小米</view>
<view>小米</view>
<view>小米</view>
<view>小米</view>
</view>
<view class="father" id="cate4">
<view>华为家居</view>
<view>小米</view>
<view>小米</view>
<view>小米</view>
<view>小米</view>
</view>
<view class="father" id="cate5">
<view>华为家居</view>
<view>小米</view>
<view>小米</view>
<view>小米</view>
<view>小米</view>
</view>
<view class="father">
<view>华为家居</view>
<view>小米</view>
<view>小米</view>
<view>小米</view>
<view>小米</view>
</view>
<view class="father">
<view>华为家居</view>
<view>小米</view>
<view>小米</view>
<view>小米</view>
<view>小米</view>
</view>
<view class="father">
<view>华为家居</view>
<view>小米</view>
<view>小米</view>
<view>小米</view>
<view>小米</view>
</view>
<view class="father">
<view>华为家居</view>
<view>小米</view>
<view>小米</view>
<view>小米</view>
<view>小米</view>
</view>
</scroll-view>
</view>
data: {
cateId:''
},
_jumpCate(e){
let {cateId} = e.currentTarget.dataset;
console.log(cateId)
this.setData({
cateId
})
},
5.表单组件
搜集数据
表单元素的vlue,表单提交,元素上需要添加name属性
<!--
原生input
type
-->
<view class="page">
<form bindsubmit="_submitTh" bindreset="_resetTh">
<view class="title">请填写以下信息</view>
<view class="_Title">姓名:</view>
<!-- placeholder 提示文字 -->
<input class="_input" placeholder="请输入姓名" name="username"/>
<view class="_Title">联系方式:</view>
<!-- value 默认表单元素的值 -->
<input class="_input" placeholder="请输入手机号" value="158" name="phone" type="number" />
<view class="_Title">证件号:</view>
<!-- type:number idcart digit -->
<input class="_input" placeholder="请输入身份证号" type="idcard" name="cardid" />
<view class="_Title">密码:</view>
<!-- password 是否是密码框 -->
<input class="_input" placeholder="请输入密码" password name="password" />
<view class="_Title">性别</view>
<radio-group class="radio_group" bindchange="sexChange" name="sex">
<view>
<radio value="男">男</radio>
</view>
<view>
<radio value="女" checked>女</radio>
</view>
<view>
<radio value="保密" color="red">保密</radio>
</view>
</radio-group>
<view class="_Title">您的爱好是什么</view>
<checkbox-group name="hobby">
<checkbox value="爬山" color="red">爬山</checkbox>
<checkbox value="游泳" checked>游泳</checkbox>
<checkbox value="篮球">篮球</checkbox>
</checkbox-group>
<view class="_Title">您平时去哪里锻炼</view>
<checkbox-group bindchange="_checkGroup" name="where">
<checkbox value="家里" color="red">家里</checkbox>
<checkbox value="体育馆" checked>体育馆</checkbox>
<checkbox value="公园">公园</checkbox>
</checkbox-group>
<view class="_Title" name="agree">您是否同意我们联系您</view>
<view>
<!-- type switch/checkbox -->
<switch type="checkbox" bindchange="_chooseArgnt"></switch>
</view>
<view class="btn">
<!--
size :default/mini/
type:parimary/default/warning
form-type:submit/reset
-->
<button class="submit" size="mini" type="parimary" form-type="submit">提交</button>
<button class="reset" size="mini" type="warn" form-type="reset">重置</button>
</view>
</form>
</view>
css
.page{
padding: 15rpx 30rpx;
}
.title{
height: 82rpx;
line-height: 82rpx;
color: white;
background: #ff4500;
font-size: 40rpx;
padding-left: 30rpx;
}
._Title{
font-size: 50rpx;
font-weight: bold;
padding: 30rpx 0 10rpx 0;
}
._input{
border:1px solid #646464;
height: 60rpx;
line-height: 60rpx;
padding-left:30rpx;
border-radius: 20rpx;
}
.radio_group view{
margin-bottom: 15rpx;
}
.btn{
display: flex;
justify-content: space-between;
}
.submit{
}
.reset{
}
js
// pages/04form/04form.js
Page({
/**
* 页面的初始数据
*/
data: {
},
_checkGroup(e) {
// 复选框的数据结构为数组
console.log(e)
},
sexChange(e) {
// 单选框里的数据结构为字符串
console.log(e)
},
_chooseArgnt(e) {
console.log(e)
},
_submitTh(e) {
console.log(e)
},
_resetTh(e) {
console.log(e)
}
})
6.媒体组件
image
<!--
图片
懒加载
src
lazy-load:是否启用懒加载
show-menu-by-longpress 是否展示小程序菜单
小程序码放到图片上
-->
<image src="/static/erha1.jpg" class="img1" />
<image src="/static/erha1.jpg" class="img1" bindload="_load" />
<!-- <image src="/static/er22ha1.jpg" class="img1" binderror="_error" /> -->
<image src="/static/erha1.jpg" class="img1" bindload="_load" show-menu-by-longpress />
<image src="/static/erha1.jpg" class="img1" bindload="_numAdd" lazy-load />
<image src="/static/erha2.jpg" class="img1" bindload="_numAdd" lazy-load />
<image src="/static/hello.jpg" class="img1" bindload="_numAdd" lazy-load/>
<image src="/static/erha1.jpg" class="img1" bindload="_numAdd" lazy-load />