7、样式 WXSS
7.1、尺寸单位
1.小程序中 不需要主动来引用样式文件
2.需要把页面中某些元素的单位 由 px改成rpx
1px= 2rpx
3.存在一个设计稿,宽度414或者未知page
1、设计稿page存在一个元素 宽度 100px
2、拿以上的需求去实现不同宽度的页面适配
例如:page px = 750rpx
1px = 750rpx/page
100px = 750rpx*100/page
4.利用一个属性 calc 属性 css和wxss都支持一个属性
page与rpx之间不要留空格
运算符的两边不要留空格
width:calc(750rpx* 设计稿元素宽度数值/设计稿宽度数值)
7.2、样式导入
wxss中直接支持,样式导入功能
也可以和less中的导入混用
使用 @import
语句可以导入外联样式表,只支持相对路径
实践
-
在文件中新建一个styles文件,之后建立common.wxss文件
view{ color: blueviolet; font-size: 100rpx; }
-
直接在页面所对应wxss文件中引用即可
@import "../../styles/common.wxss";
7.3、选择器
在小程序的选择器与之前在css中的非常像,但是 特别注意
小程序不支持通配符 *
.
选择器 | 样例 | 样例描述 | 权重优先级 |
---|---|---|---|
.class | .intro | 选择所有拥有class=“intro”的组件 | 10 |
element | view | 选择所有view组件 | 1 |
#id | #firstname | 选择拥有id=“firstname”的组件 | 100 |
element,element | view,checkbox | 选择所有文档的view组件和所有的checkbox组件 | |
nth-child(n) | view:nth-child(n) | 选择某个索引的标签 | |
::after | view::after | 在view组件后边插入内容 | |
::before | view::before | 在view组件前边插入内容 | |
style | 1000 | ||
!important | 正无穷 |
7.4、小程序中使用less
原生小程序不支持less,某些小程序的框架大体都支持,如 wepy,mpvue,taro等。但是仅仅因为一个less功能,而去引用一个框架,肯定是不可取的,因此可以用以下方式来实现
-
编辑器是vscode
-
安装插件 easy less
-
在vscode的设置中加入如下配置
-
点击左下角设置
-
点击右上角左1按钮
-
添加如下图第3、4行配置
-
-
在要编写样式的地方,新建less文件,如index.less,然后正常编辑即可。
实践
1、注意,在vscode中的css注释会跟着过去,而less不会
在less文件书写好样式之后,他会自动的转换成css结构。具体代码如下,左边是在vscode中编写的代码
2、尝试导入,如下图
8、常见组件
8.1、view标签 div
属性 | 类型 | 默认值 | 必填 | 说明 | 最低版本 |
---|---|---|---|---|---|
hover-class | string | none | 否 | 指定按下去的样式类。当 hover-class="none" 时,没有点击态效果 | 1.0.0 |
hover-stop-propagation | boolean | false | 否 | 指定是否阻止本节点的祖先节点出现点击态 | 1.5.0 |
hover-start-time | number | 50 | 否 | 按住后多久出现点击态,单位毫秒 | 1.0.0 |
hover-stay-time | number | 400 | 否 | 手指松开后点击态保留时间,单位毫秒 | 1.0.0 |
8.2、text 类似 span
-
文本标签
-
只能嵌套text
-
长按文字可以复制(只有该标签有这个功能)
-
可以对 空格 进行编码
属性名 类型 默认值 说明 selectable Boolean false 文本是否可选 decode Boolean false 是否解析
实战
<text selectable decode>abc长按文字复制
123 < > & '    </text>
解析:直接写上属性就行,可以不用赋值,当然,也可以和下面代码一样写
<text selectable="{{true}}" decode="{{true}}">
未晞 &
</tex
8.3、image
这个与之前的很不一样
-
图片标签,image组件默认宽度为320px,高度为240px
-
支持懒加载
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
src | String | 图片资源地址 | |
mode | String | ‘scaleToFill’ | 图片裁剪、缩放的模式 |
lazy-load | Boolean | false | 图片懒加载 |
统一使用外网图片链接。
推荐使用
土豆图床[图床 - 免费图片外链 (imgloc.com)](https://imgloc.com/)
image 图片标签
1、src 指定要加载的图片的路径
图片存在默认的宽度和高度 320 * 240
2、mode 决定 图片内容如何 和 图片标签 宽高 做适配
<1>scaleToFill 默认值 不保存纵横比缩放图片,使图片的宽高完全拉伸至填满 image元素
<2>☆aspectFit 保持宽高比,确保图片的长边显示出来,页面轮播图常用
<3>aspectFill 保持纵横比缩放图片,只保证图片的 短 边 能够完全显示出来。少用
<4>☆widthFix 以前web的图片的宽度指定了之后,高度 会自己按比例来调整 常用
<5>bottom 类似以前的background-position
3、小程序当中的图片 直接就支持,懒加载 lazy-load
1 lazy-load 会自己判断 当图片出现在视口上下三屏的高度之内的时候,自己开始加载图片
wxml中的代码如下:
<image mode="scaleToFill" src="https://s1.328888.xyz/2022/08/18/3zeG0.jpg"></image>
8.4、wisper && wisper-item
1 、轮播图外层容器 swiper
2 、每一个轮播项 swiper-item
3 、swiper标签 存在默认样式
(1)width 100%
(2)height 150px image存在默认高度和宽度,240*320
(3)swiper 高度 无法实现由内容撑开
4、先找出来 原图的宽度和高度 等比例 给swiper 定宽度和高度
补充内容
swiper高度 / swiper宽度 = 原图的高度 / 原图的宽度
用calc
1vw=1%的宽度 100vw也就是页面宽度,同样vh也是同一样的道理
vw是一个视口单位,是指相对于视口的宽度;1vw等于视口宽度的1%,比如浏览器的宽度为1920px,则“1vw=19.2px”。
注意:https可加可不加
将图片下载到本次,观察像素,之后利用公式算出数据
5、autoplay自动轮播
属性 | 类型 | 默认值 | 必填 | 说明 | 最低版本 | |
---|---|---|---|---|---|---|
显示 指示器、分页器、索引器 | indicator-dots | boolean | false | 否 | 是否显示面板指示点 | 1.0.0 |
indicator-color | color | rgba(0, 0, 0, .3) | 否 | 指示点颜色 | 1.1.0 | |
indicator-active-color | color | #000000 | 否 | 当前选中的指示点颜色 | 1.1.0 | |
autoplay | boolean | false | 否 | 是否自动切换 | 1.0.0 | |
current | number | 0 | 否 | 当前所在滑块的 index | 1.0.0 | |
circular | boolean | false | 否 | 是否采用衔接滑动 | 1.0.0 | |
interval | number | 5000 | 否 | 自动切换时间间隔 | 1.0.0 |
实训
**wxml**中的内容
<swiper autoplay interval="1000" circular indicator-dots indicator-color="#009845">
<swiper-item><image mode="widthFix" src="//img10.360buyimg.com//n0/jfs/t1/205231/7/8189/151241/6151528eE89b3defa/22112f6150bc2005.jpg"/></swiper-item>
<swiper-item><image mode="widthFix" src="https://img.alicdn.com/tfs/TB1R5fsgyDsXe8jSZR0XXXK6FXa-281-80.jpg"/></swiper-item>
<swiper-item><image mode="widthFix" src="https://img30.360buyimg.com/n1/jfs/t1/1457/22/12544/54357/5bd40d5bEe6f2df8c/9a98906fac6abaca.jpg"/></swiper-item>
</swiper>
wxss中的内容
swiper{
width: 100%;
height: calc(100vw* 800/800);
}
image{
width: 100%;
}
8.5、导航 navigator
8.5.1、url
-
块级元素默认 会换行 可以直接加宽度与高度
-
要跳转的页面路径,既可以是绝对路径也可以是相对路径
属性说明
属性 | 类型 | 默认值 | 必填 | 说明 | 最低版本 |
---|---|---|---|---|---|
target | string | self | 否 | 在哪个目标上发生跳转,默认当前小程序。可选值:self/miniProgram | 2.0.7 |
url | string | 否 | 当前小程序内的跳转链接 | 1.0.0 | |
open-type | string | navigate | 否 | 跳转方式。 | 1.0.0 |
delta | number | 1 | 否 | 当 open-type 为 'navigateBack' 时有效,表示回退的层数 | 1.0.0 |
app-id | string | 否 | 当target="miniProgram" 且open-type="navigate" 时有效,要打开的小程序 appId | 2.0.7 | |
path | string | 否 | 当target="miniProgram" 且open-type="navigate" 时有效,打开的页面路径,如果为空则打开首页 | 2.0.7 | |
extra-data | object | 否 | 当target="miniProgram" 且open-type="navigate/navigateBack" 时有效,需要传递给目标小程序的数据,目标小程序可在 App.onLaunch() ,App.onShow() 中获取到这份数据。详情 | 2.0.7 | |
version | string | release | 否 | 当target="miniProgram" 且open-type="navigate" 时有效,要打开的小程序版本 | 2.0.7 |
short-link | string | 否 | 当target="miniProgram" 时有效,当传递该参数后,可以不传 app-id 和 path。链接可以通过【小程序菜单】->【复制链接】获取。 | 2.18.1 | |
hover-class | string | navigator-hover | 否 | 指定点击时的样式类,当hover-class="none" 时,没有点击态效果 | 1.0.0 |
hover-stop-propagation | boolean | false | 否 | 指定是否阻止本节点的祖先节点出现点击态 | 1.5.0 |
hover-start-time | number | 50 | 否 | 按住后多久出现点击态,单位毫秒 | 1.0.0 |
hover-stay-time | number | 600 | 否 | 手指松开后点击态保留时间,单位毫秒 | 1.0.0 |
open-type有效值
值 | 说明 |
---|---|
navigate | 保留当前页面,跳转到应用内的某个页面,但是不能跳到tabbar页面 |
redirect | 关闭当前页面,跳转到应用内的某个页面,但是不允许跳转到tabbar页面 |
switchTab | 跳转到 taBar 页面,并关闭其他所有非 tabBar页面 |
reLaunch | 关闭所有页面,打开到应用内的某个页面 |
navigateBack | 关闭当前页面,返回上一页面或多级页面,可通过getCurrentPages()获取当前的页面栈,决定需要返回几层 |
exit | 退出小程序,target=“miniprograme”时生效00 |
实训
wxml中的
<navigator url="/pages/demo07/demo07">轮播图界面</navigator>
<navigator url="/pages/index/index">轮播图界面</navigator>
<navigator open-type="redirect" url="/pages/index/index">直接跳转到tabBar页面 redirect</navigator>
<navigator open-type="switchTab" url="/pages/index/index">switchTab直接跳转到tabBar页面</navigator>
<navigator open-type="reLaunch" url="/pages/index/index">reLaunch直接跳转到tabBar页面</navigator>
8.6、rich-text 富文本标签
1、nodes属性来实现
-
接收标签字符串
// 直接从别人网站上复制,我这个是从淘宝上复制的,由于没有样式,所以无法显示和他的一样 Page({ /** * 页面的初始数据 */ data: { html:'<div class="_3myJcyLZ"><div class="_1Hj_hKxL _3_kIlG9D"><div class="_3UIbf5C5 _2RTfeKGX"><div class="_2kXlUAd0"><div class="_2pERGifx"><img class="_2xc6f8CK" src="/pages/samples/taobao/e7244a1914f1.png"><div class="_3nqpFKAH">天猫新品</div></div><div class="_3iLcLLoA"><img class="_3rq9lCix" src="/pages/samples/taobao/553ca575fecc.png"><div class="_3Lld5JOA">今日爆款</div></div><div class="_2jsDpzsF"><img class="_1yQSxTYk" src="/pages/samples/taobao/ccfaf1b16da1.png"><div class="rfA_PeVb">天猫国际</div></div><div class="_39eUQdgJ"><img class="_2XIqu8DZ" src="/pages/samples/taobao/089ce1104d7f.png"><div class="hE7wsfpP">饿了么</div></div><div class="CKF3iJ65"><img class="jfkYqt8M" src="/pages/samples/taobao/e6760c4f36de.png"><div class="_2RaLrmzg">天猫超市</div></div><div class="psPYHD2r"><img class="k5f7-zva" src="/pages/samples/taobao/1e8964c42eed.png"><div class="_3gLMMUzV">分类</div></div><div class="PVNcjxLL"><img class="_33fmYVCh" src="/pages/samples/taobao/c14b5f64ddbf.png"><div class="_3kZekxQO">天猫美食</div></div><div class="_2WyJ0t06"><img class="_3jA1N7CF" src="/pages/samples/taobao/839646fd1917.png"><div class="_2QKAdCVs">阿里健康</div></div><div class="_2OWmrtEn"><img class="_21D19WrU" src="/pages/samples/taobao/938df62c8298.png"><div class="_1UNF08ta">口碑生活</div></div></div><div class="_1dfm7Z-6 _2kXlUAd0"><div class="iwmUlOtT"><img class="_1vjQrJue" src="/pages/samples/taobao/6ed9d5a0b95e.png"><div class="_29rHdjMH">充值中心</div></div><div class="_1GGVUMWs"><img class="_1r29uilN" src="/pages/samples/taobao/c30a8d092353.png"><div class="_36oxd8Bn">机票酒店</div></div><div class="_1NV7oWpk"><img class="_2-nYQqId" src="/pages/samples/taobao/28ee466b58df.png"><div class="_2taLHS1d">金币庄园</div></div><div class="MaVbOQ4X"><img class="_3qzVjENk" src="/pages/samples/taobao/2cee037878ff.png"><div class="_1HpIiQa6">阿里拍卖</div></div><div class="_20tMPGVy"><img class="_2Zl_4tvs" src="/pages/samples/taobao/8bbe34bf6abf.png"><div class="_3YAosn9x">淘宝吃货</div></div><div class="WVY6pkP-"><img class="_3uNrW-67" src="/pages/samples/taobao/ae3bb07227cf.png"><div class="_3OmYYzqq">闲鱼</div></div><div class="_1AT1luG2"><img class="_10CqQLEW" src="/pages/samples/taobao/33f1e6c0644b.png"><div class="_2z0GMY1D">会员中心</div></div><div class="_3Uxw2_hL"><img class="_1hHo5Ad4" src="/pages/samples/taobao/f4f42305d557.png"><div class="_32rEhL_l">造点新货</div></div><div class="q1_0TIdY"><img class="vC4xOnyf" src="/pages/samples/taobao/19f8417afb55.png"><div class="_367w-1nQ">土货鲜食</div></div></div></div></div></div>' } }) <!--参照淘宝触屏版--> <rich-text nodes="{{html}}"></rich-text>
-
接收对象数组
// pages/demo09/demo09.ts
Page({
/**
* 页面的初始数据
*/
data: {
// 1.标签字符串 最常用
// 2 对象数组
html1:[{
// 1 div标签 name属性来指定
name:"div",
// 2 标签上有哪些属性
attrs:{
// 标签上的属性 class style
class:"my_div",
style:"color:red;"
},
// 3 子节点 children 要接受的数据类型 和 nodes 第二渲染方式的数据类型一致
children:[{
name:"p",
attrs:{},
// 发文本
children:[{
type:"text",
text:"hello"
}]
}
]
}]
}
})
<!--参照淘宝触屏版-->
<rich-text nodes="{{html1}}"></rich-text>
Bug & Tip
-
tip
: nodes 不推荐使用 String 类型,性能会有所下降。 -
tip
:rich-text
组件内屏蔽所有节点的事件。 -
tip
: attrs 属性不支持 id ,支持 class 。 -
tip
: name 属性大小写不敏感。 -
tip
: 如果使用了不受信任的 HTML 节点,该节点及其所有子节点将会被移除。 -
tip
: img 标签仅支持网络图片。 -
tip
: 如果在自定义组件中使用rich-text
组件,那么仅自定义组件的 wxss 样式对rich-text
中的 class 生效。
8.7、button
8.7.1、外观属性
属性 | 类型 | 默认值 | 必填 | 说明 | 最低版本 |
---|---|---|---|---|---|
size | string | default | 否 | 按钮的大小 | 1.0.0 |
default默认大小 mini小尺寸 | |||||
type | string | default | 否 | 按钮的样式类型 | 1.0.0 |
合法值说明:primary绿色 default白色 warn红色 | |||||
plain | boolean | false | 否 | 按钮是否镂空,背景色透明 | 1.0.0 |
disabled | boolean | false | 否 | 是否禁用 | 1.0.0 |
loading | boolean | false | 否 | 名称前是否带 loading 图标 | 1.0.0 |
form-type | string | 否 | 用于 form 组件,点击分别会触发 form 组件的 submit/reset 事件 | 1.0.0 | |
合法值说明 submit提交表单reset重置表单 | |||||
open-type | string | 否 | 微信开放能力 | 1.1.0 |
<button>默认按钮</button>
<button size="mini">mini默认按钮</button>
<button type="primary" plain>镂空默认按钮</button>
<button type="default" plain loading>loading默认按钮</button>
8.7.2、button开发能力
值 | 说明 |
---|---|
contact | 打开客服会话,如果用户在会话中点击消息卡片后返回小程序,可以从 bindcontact 回调中获得具体信息,具体说明 (小程序插件中不能使用) |
share | 触发用户转发,使用前建议先阅读使用指引 |
getPhoneNumber | 获取用户手机号,可以从 bindgetphonenumber 回调中获取到用户信息,具体说明 (小程序插件中不能使用) |
getUserInfo | 获取用户信息,可以从 bindgetuserinfo 回调中获取到用户信息 (小程序插件中不能使用) |
launchApp | 打开APP,可以通过 app-parameter 属性设定向 APP 传的参数具体说明 |
openSetting | 打开授权设置页 |
feeback | 打开“意见反馈”页面,用户可提交反馈内容并上传日志,开发者可以登录小程序管理后台后进入左侧菜单“客服反馈”页面获取到反馈内容 |
<!-- button 开发能力
open-type:
1 contact 直接打开 客服对话功能 需要在微信小程序的后台配置
2 share 转发当前的小程序 到微信朋友中 不能把小程序分享到朋友圈
3 getPhoneNumber 获取当前用户的手机号码信息,结合一个事件来使用,不是企业的我小程序账号,没有权限来获取用户的手机号码
1 绑定一个事件 bindgetphonenumber
2 在事件的回调函数中 通过参数来获取信息
3 获取到的信息 已经加密过了。此时需要用户自己搭建小程序后台服务器,在后台服务器中进行解析 手机号码,返回到小程序中就可以看到信息了
4 getUserInfo 获取当前用户的个人信息
1 使用方法 类似 获取用户的手机号码
2 可以直接获取 不存在加密的字段
5 launchApp 在小程序当中 直接打开app
1 需要现在 app中 通过app的某个链接 打开小程序
2 在小程序中 再通过 这个功能 重新打开app
3 找到 京东的app 和 京东的小程序
6 openSetting 打开小程序内置的 授权页面
1 授权页面中 只会出现 用户曾经点击过的 权限
7 feeback 打开小程序内置的 意见反馈页面
1 只能够通过真机调试来打开
-->
<button open-type="contact">contact</button>
<button open-type="share">share</button>
<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">getPhoneNumber</button>
<button open-type="getUserInfo" bindgetuserinfo="getUserInfo">getUserInfo</button>
<button open-type="launchApp">launchApp</button>
<button open-type="openSetting">openSetting</button>
<button open-type="feedback">feedback</button>
open-type 的 contact 的实现流程
-
将小程序的appid 由测试号 改为 自己的appid
-
登录微信小程序官网小程序 (qq.com),添加 客服-微信
-
为了方便演示,老师自己准备了两个账号 i.普通 用户A
ii.客服-微信B
实践
// pages/demo11/demo11.wxml
<button open-type="contact">contact</button>
<button open-type="share">share</button>
<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">getPhoneNumber</button>
<button open-type="getUserInfo" bindgetuserinfo="getUserInfo">getUserInfo</button>
<button open-type="launchApp">launchApp</button>
<button open-type="openSetting">openSetting</button>
<button open-type="feedback">feedback</button>
// pages/demo11/demo11.ts
Page({
// 获取用户的手机号码信息
getPhoneNumber(e: any){
console.log(e);
},
// 获取用户的个人信息
getUserInfo(e: any){
console.log(e)
}
})
8.8、icon
属性说明
属性 | 类型 | 默认值 | 必填 | 说明 | 最低版本 |
---|---|---|---|---|---|
type | string | 是 | icon的类型,有效值:success, success_no_circle, info, warn, waiting, cancel, download, search, clear | 1.0.0 | |
size | number/string | 23 | 否 | icon的大小,单位默认为px,2.4.0起支持传入单位(rpx/px),2.21.3起支持传入其余单位(rem 等)。 | 1.0.0 |
color | string | 否 | icon的颜色,同 css 的color | 1.0.0 |
补充知识点 block标签
<block/> 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。
因为 wx:if 是一个控制属性,需要将它添加到一个标签上。如果要一次性判断多个组件标签,可以使用一个 <block/> 标签将多个组件包装起来,并在上边使用 wx:if 控制属性。
< block wx:if = "{{true}}" > < view > view1 </ view > < view > view2 </ view > </ block >3.类似 block wx:if,也可以将 wx:for 用在<block/>标签上,以渲染一个包含多节点的结构块。例如:
< block wx:for = "{{[1, 2, 3]}}" > < view > {{index}}: </ view > < view > {{item}} </ view > </block>
实训
(1)icon.wxss
/* pages/demo12/icon.wxss */
.container{
padding-left: 10px;
padding-right: 0px;
font-size: 10px;
display: flex;
align-items: center;
}
.icon-box{
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
margin-bottom: 20px;
}
.icon-small-wrp{
display: flex;
flex-direction: column-reverse;
align-items: center;
justify-content:center ;
margin-top: 30px;
margin-left:50rpx ;
height: 150rpx;
width: 350rpx;
}
.icon-box-ctn{
margin-left: 2px;
font-size: 16px;
margin-bottom: 10px;
flex-direction: column;
margin-left:20px ;
}
.icon-small{
width:50px;
margin-right: 10rpx;
widows: 260rpx;height:200rpx;
display:inline-flex;
flex-direction:column;
justify-content:end;
}
.icon-box-img{
width: 96;
margin-right: 20rpx;
widows: 260rpx;height:200rpx;
display:inline-flex;
flex-direction:column;
justify-content:end;
}
.icon-box-title{
font:bolder;
}
.icon-box-desc{
font-size: medium;
color: darkgrey;
}
(2)icon.wxml
<!--pages/demo12/icon.wxml-->
<view class="container">
<view class="icon-box">
<icon class="icon-box-img" type="success" size="93"></icon>
<view class="icon-box-ctn">
<view class="icon-box-title">成功</view>
<view class="icon-box-desc">用于表示操作顺利完成</view>
</view>
</view>
<view class="icon-box">
<icon class="icon-box-img" type="info" size="93"></icon>
<view class="icon-box-ctn">
<view class="icon-box-title">提示</view>
<view class="icon-box-desc">用于表示信息提示;也常用于缺乏条件的操作拦截,提示用户所需信息</view>
</view>
</view>
<view class="icon-box">
<icon class="icon-box-img" type="warn" size="93" color="#C9C9C9"></icon>
<view class="icon-box-ctn">
<view class="icon-box-title">普通警告</view>
<view class="icon-box-desc">用于表示操作后将引起一定后果的情况;也用于表示由于系统原因而造成的负向结果</view>
</view>
</view>
<view class="icon-box">
<icon class="icon-box-img" type="warn" size="93"></icon>
<view class="icon-box-ctn">
<view class="icon-box-title">强烈警告</view>
<view class="icon-box-desc">用于表示由于用户原因造成的负向结果;也用于表示操作后将引起不可挽回的严重后果的情况</view>
</view>
</view>
<view class="icon-box">
<icon class="icon-box-img" type="waiting" size="93"></icon>
<view class="icon-box-ctn">
<view class="icon-box-title">等待</view>
<view class="icon-box-desc">用于表示等待,告知用户结果需等待</view>
</view>
</view>
<view class="icon-box">
<view class="icon-small-wrp">
<icon class="icon-small" type="success_no_circle" size="23"></icon>
</view>
<view class="icon-box-ctn">
<view class="icon-box-title">多选控件图标_已选择</view>
<view class="icon-box-desc">用于多选控件中,表示已选择该项目</view>
</view>
</view>
<view class="icon-box">
<view class="icon-small-wrp">
<icon class="icon-small" type="circle" size="23"></icon>
</view>
<view class="icon-box-ctn">
<view class="icon-box-title">多选控件图标_未选择</view>
<view class="icon-box-desc">用于多选控件中,表示该项目可被选择,但还未选择</view>
</view>
</view>
<view class="icon-box">
<view class="icon-small-wrp">
<icon class="icon-small" type="warn" size="23"></icon>
</view>
<view class="icon-box-ctn">
<view class="icon-box-title">错误提示</view>
<view class="icon-box-desc">用于在表单中表示出现错误</view>
</view>
</view>
<view class="icon-box">
<view class="icon-small-wrp">
<icon class="icon-small" type="success" size="23"></icon>
</view>
<view class="icon-box-ctn">
<view class="icon-box-title">单选控件图标_已选择</view>
<view class="icon-box-desc">用于单选控件中,表示已选择该项目</view>
</view>
</view>
<view class="icon-box">
<view class="icon-small-wrp">
<icon class="icon-small" type="download" size="23"></icon>
</view>
<view class="icon-box-ctn">
<view class="icon-box-title">下载</view>
<view class="icon-box-desc">用于表示可下载</view>
</view>
</view>
<view class="icon-box">
<view class="icon-small-wrp">
<icon class="icon-small" type="info_circle" size="23"></icon>
</view>
<view class="icon-box-ctn">
<view class="icon-box-title">提示</view>
<view class="icon-box-desc">用于在表单中表示有信息提示</view>
</view>
</view>
<view class="icon-box">
<view class="icon-small-wrp">
<icon class="icon-small" type="cancel" size="23"></icon>
</view>
<view class="icon-box-ctn">
<view class="icon-box-title">停止或关闭</view>
<view class="icon-box-desc">用于在表单中,表示关闭或停止</view>
</view>
</view>
<view class="icon-box">
<view class="icon-small-wrp">
<icon class="icon-small" type="search" size="14"></icon>
</view>
<view class="icon-box-ctn">
<view class="icon-box-title">搜索</view>
<view class="icon-box-desc">用于搜索控件中,表示可搜索</view>
</view>
</view></view>
(3)icon.ts
Page({
data: {
iconSize: [20, 30, 40, 50, 60, 70],
iconColor: [
'red', 'orange', 'yellow', 'green', 'rgb(0,255,255)', 'blue', 'purple'
],
iconType: [
'success', 'success_no_circle', 'info', 'warn', 'waiting', 'cancel', 'download', 'search', 'clear'
]
}
})
8.9、radio
属性说明
属性 | 类型 | 默认值 | 必填 | 说明 | 最低版本 |
---|---|---|---|---|---|
value | string | 否 | radio 标识。当该radio 选中时,radio-group 的 change 事件会携带radio的value | 1.0.0 | |
checked | boolean | false | 否 | 当前是否选中 | 1.0.0 |
disabled | boolean | false | 否 | 是否禁用 | 1.0.0 |
color | string | #09BB07 | 否 | radio的颜色,同 css 的color |
需要搭配 raido-group 一起使用
实战
wxml中的内容
<!--
radio单选框
1 radio标签 必须要和 父元素 radio-group 来使用
2 value 选中的单选框的值
3 需要给 radio-group 绑定 change事件
4 需要在页面中显示 选中的值
-->
<radio-group bindchange="handleChange">
<radio color="red" value="male">男</radio>
<radio value="female">女</radio>
</radio-group>
<view>你选中的性别是:{{gender}}</view>
ts中的内容
Page({
/**
* 页面的初始数据
*/
data: {
gender:""
},
handleChange(e){
// 1 获取单选框中的值
let gender = e.detail.value;
// 2 把值 赋值给 datra中的数据
this.setData({
// gender:gender
gender
})
}
})
效果图
8.10、checkbox
实战
wxml
<view>
<checkbox-group bindchange="handleItemChange">
<checkbox value="{{item.value}}" wx:for="{{list}}" wx:key="id">{{item.name}}
</checkbox>
</checkbox-group>
<view>
选中的水果:{{checkedList}}
</view>
</view>
// pages/demo14/demo14.ts
Page({
/**
* 页面的初始数据
*/
data: {
list:[{
id:0,
name:"苹果✪",
value:"apple"
},
{
id:1,
name:"葡萄",
value:"grape"
},
{
id:2,
name:"香蕉",
value:"banana"
}],
checkedList:[]
},
// 复选框的选中的值
handleItemChange(e){
// 1 获取被选中的复选框的值
const checkedList = e.detail.value;
// 2 进行赋值
this.setData({
checkedList
})
}
})
9、自定义组件
类似于vue或者react中的自定义组件
小程序允许我们使用自定义组件的方式来构建页面
9.1、创建自定义组件
类似于页面,一个自定义组件由 json、wxml、wxss、js 4个文件组成
可以在微信开发者工具中快速创建组件的文件结构
demo.json
{
"usingComponents": {
"Tabs":"../../components/Tabs/Tabs"
}
}
<!--pages/demo15/demo15.wxml-->
<Tabs></Tabs>
成果显示
9.2、标题激活选中
实训
WXML
<!--components/Tabs/Tabs.wxml-->
<view class="tabs">
<view class="tabs_title">
<!-- <view class="title_item active">首页</view>
<view class="title_item">原创</view>
<view class="title_item">分类</view>
<view class="title_item">关于</view> -->
<view
wx:for="{{tabs}}"
wx:key="id"
class="title_item {{item.isActive?'active':''}}"
bindtap="handleItemTap"
data-index="{{index}}"
>{{item.name}}</view>
</view>
<view class="tabs_content">内容</view>
</view>
// components/Tabs/Tabs.ts
Component({
/**
* 组件的属性列表
*/
properties: {
},
/**
* 组件的初始数据
*/
data: {
tabs:[{
id:0,
name:"首页",
isActive:true
},
{
id:1,
name:"原创",
isActive:false
},
{
id:2,
name:"分类",
isActive:false
},
{
id:3,
name:"关于",
isActive:false
}
]},
/**
* 组件的方法列表
* 1 页面 .js 文件中,存放事件回调函数的时候,存放在data同层级下
* 2 组件 .js 文件中,存放事件回调函数的时候,必须要存在在methods中
*/
methods: {
handleItemTap(e: { currentTarget: { dataset: { index: any; }; }; }){
/*1 绑定点击事件 需要在methods中绑定
2 获取被点击的索引
3 获取原数组
4 对数组循环
1 对每一个循环性 选中属性改为 false
2 给 当前的索引的项 添加激活选中效果就可以了
*/
// 2 获取索引
const {index} = e.currentTarget.dataset;
// 3 获取data中的数组
// 解构 对 复杂类型进行结构的时候, 复制了一份 变量的引用而已
// 最严谨的做法,重新拷贝一份 数组,再对这个数组的备份进行处理
// let tabs = JSON.parse(JSON.stringify(this.data.tabs));
// 不要直接修改 this.data 数据
let {tabs} = this.data;
// let tabs = this.data.tabs;
// 4 循环数组
// [].forEach 遍历数组 遍历数组的时候,修改了 V ,也会导致源数组被修改
tabs.forEach((v,i)=>i===index?v.isActive=true:v.isActive=false);
this.setData({
tabs
})
},
}
})
9.3、自定义组件--父向子传递数据
一、父组件wxml
<!--
demo15.wxml
1 父组件(页面) 向子组件 传递数据, 通过从标签属性的方式来传递
1 在子组件上进行接收
2 把这个数据当成是data中的数据直接用就行
-->
<Tabs aaa="a123a"></Tabs>
改为:
<Tabs tabs="{{tabs}}"></Tabs>
二、子组件 js
// components/Tabs/Tabs.ts
Component({
/**
* 组件的属性列表,里面存放的是 要从父组件中接收的数据
*/
properties: {
// 要接收的数据的名称
aaa:{
// type 要接收的数据的类型
type:String,
// vlaue 默认值
value:""
}
改为:tabs:{
type:Array,
value:[]
}
},...
三、子组件的wxml
<!--components/Tabs/Tabs.wxml-->
<view>{{aaa}}</view>
改为<Tabs tabs="{{tabs}}"></Tabs>
效果图:
9.4、自定义组件--子向父传递数据
找数据的时候 首先在data中找,data中的没有找到就去properties中找
正确的逻辑是:父向子传递数据-->在子组件的自定义事件方法中(获得并处理父组件传递来的数据-->将处理结果数据赋值给子组件data:{tabs:tabs})
this.setData({
tabs
})
这一步相当于在子组件中写
data:{tabs}
存在的问题
希望点击不同的页面的时候,父组件的appdata的isActive能够改变。
之前的写法都是,父组件的tabs一直在覆盖子组件的tabs,所以不改变。而现在是让父组件的tabs再回到父组件中进行处理,形成数据闭环
子组件的js文件
// components/Tabs/Tabs.ts
Component({
/**
* 组件的属性列表,里面存放的是 要从父组件中接收的数据
*/
properties: {
// // 要接收的数据的名称
// aaa:{
// // type 要接收的数据的类型
// type:String,
// // vlaue 默认值
// value:""
// }
tabs:{
type:Array,
value:[]
}
},
/**
* 组件的初始数据
*/
data:{},
// data: {
// tabs:[{
// id:0,
// name:"首页",
// isActive:true
// },
// {
// id:1,
// name:"原创",
// isActive:false
// },
// {
// id:2,
// name:"分类",
// isActive:false
// },
// {
// id:3,
// name:"关于",
// isActive:false
// }
// ]},
/**
* 组件的方法列表
* 1 页面 .js 文件中,存放事件回调函数的时候,存放在data同层级下
* 2 组件 .js 文件中,存放事件回调函数的时候,必须要存在在methods中
*/
methods: {
handleItemTap(e: { currentTarget: { dataset: { index: any; }; }; }){
/*1 绑定点击事件 需要在methods中绑定
2 获取被点击的索引
3 获取原数组
4 对数组循环
1 对每一个循环性 选中属性改为 false
2 给 当前的索引的项 添加激活选中效果就可以了
///
☺☺☺ 5 点击事件触发的时候,触发父组件中的自定义事件,同时传递数据 给父组件
this.triggerEvent("父组件自定义事件的名称",要传递的参数)
*/
// 2 获取索引
const {index} = e.currentTarget.dataset;
// /// 5 触发父组件中的自定义事件,同时传递数据给
☺☺☺ this.triggerEvent("itemChange",{index});
// 3 获取data中的数组
// 解构 对 复杂类型进行结构的时候, 复制了一份 变量的引用而已
// 最严谨的做法,重新拷贝一份 数组,再对这个数组的备份进行处理
// let tabs = JSON.parse(JSON.stringify(this.data.tabs));
// 不要直接修改 this.data 数据
// let {tabs} = this.data;
// let tabs = this.data.tabs;
// 4 循环数组
// [].forEach 遍历数组 遍历数组的时候,修改了 V ,也会导致源数组被修改
// tabs.forEach((v,i)=>i===index?v.isActive=true:v.isActive=false);
// this.setData({
// tabs
// })
},
}
})
父组件的wxml文件
<!--
demo15.wxml
1 父组件(页面) 向子组件 传递数据, 通过从标签属性的方式来传递
1 在子组件上进行接收
2 把这个数据当成是data中的数据直接用就行
2 子向父传递数据 通过事件的方式传递
1 在子组件的标签上加入一个自定义事件
-->
<Tabs tabs="{{tabs}}" binditemChange="handleItemChange"></Tabs>
父组件的js文件
// pages/demo15/demo15.ts
Page({
/**
* 页面的初始数据
*/
data: {
tabs:[{
id:0,
name:"首页",
isActive:true
},
{
id:1,
name:"原创",
isActive:false
},
{
id:2,
name:"分类",
isActive:false
},
{
id:3,
name:"关于",
isActive:false
}
]},
// 自定义事件,用来接收子组件传递的数据的
handleItemChange(e){
// console.log(e);
// 接收传递过来的参数
const{index} = e.detail;
console.log(index);
let {tabs} = this.data;
// 4 循环数组
tabs.forEach((v,i)=>i===index?v.isActive=true:v.isActive=false);
this.setData({
tabs
})
}
})
这样就实现了点击哪一个哪一个的对应的isActive就做出相应的改变
9.5、自定义组件--slot
slot 标签其实就是一个占位符 插槽
等到父组件调用子组件的时候,再传递标签过来,最终这些标签替换slot插槽的位置
实战
子组件的代码
demo15.wxml
<Tabs tabs="{{tabs}}" binditemChange="handleItemChange">
<block wx:if="{{tabs[0].isActive}}">0</block>
<block wx:elif="{{tabs[1].isActive}}">1</block>
<block wx:elif="{{tabs[2].isActive}}">2</block>
<block wx:else>3</block>
9.6、其他属性
9.10、定义段与示例方法
10、小程序生命周期
分为 应用生命周期和 页面生命周期
关于小程序前后台的定义和小程序的运行机制,请参考运行机制章节
10.1、应用生命周期
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
onLaunch | function | 否 | 监听小程序初始化。 | |
onShow | function | 否 | 监听小程序启动或者切前台。 | |
onHide | function | 否 | 监听小程序切后台。 | |
onError | function | 否 | 错误监听函数。 | |
onPageNotFound | function | 否 | 页面不存在监听函数。 |
实战
// app.ts
App({
// 1 应用第一次启动的就会触发的事件
onLaunch(){
// 在应用第一次启动的时候 获取用户的个人信息
console.log("onLaunch");
// js的方式来跳转 不能触发 onPageNotFound
// wx.navigateTo({
// url:'/11/22/33'
// });
},
//2 应用 被用户看到
onShow(){
// 对应用的数据或者页面效果 重置
console.log("onShow");
},
// 3 应用 被隐藏了 点击且后台(工具有一个工具栏管理)
onHide(){
// 暂停或者清除定时器
console.log("Hide");
},
// 4 应用的代码发生了报错的时候 就会触发
onError(err){
// 在应用层发生代码报错的时候,收集用户的错误信息,通过异步请求,将错误的信息发送后台去,做专门的处理
console.log("onError");
console.log(err);
},
// 5 页面找不到就会触发
// 应用第一次启动的时候,如果找不到第一个入口页面 才会触发
onPageNotFound(){
// 如果页面不存在了 通过js的方式来重新跳转页面,重新跳转到第二个首页
// 不能跳tabbar页面 导航组件类似
wx.navigateTo({
url:''
})
// console.log("onPageNotFound");
}
})
10.2、页面生命周期
实战
// pages/demo16/demo16.ts
Page({
/**
* 页面的初始数据
*/
data: {
},
/**
* 生命周期函数--监听页面加载
*/
onLoad() {
console.log('onLoad');
// onLoad中发送异步请求来初始化页面数据
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
console.log("onReady");
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
console.log("onShow");
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
console.log("onHide");
},
/**
* 生命周期函数--监听页面卸载 也是可以通过点击超链接测试,关闭当前页面=卸载当前页面
*/
onUnload() {
console.log("onUnload");
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
console.log("onPullDownRefresh");
// 页面 的数据或者效果 重新 刷新
},
/**
* 页面上拉触底事件的处理函数
* 需要让页面出现上下滚动才可以
*/
onReachBottom() {
console.log("onReachBottom");
// 上拉加载下一项数据
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
console.log("onShareAppMessage");
},
/*
页面滚动就可以触发
*/
onPageScroll(){
console.log("onPageScroll");
},
/**
* 页面的尺寸发生改变的时候触发
* 小程序 发生了横屏竖屏 切换的时候触发
*/
onResize(){
console.log("onResize");
},
/**
* 1 必须要求当前页面 也是tabbar页面
* 2 点击自己的tab item才会被触发
*/
onTabItemTap(){
console.log("onTabItemTap");
}
})
<!--pages/demo16/demo16.wxml-->
<navigator url="/pages/demo16/demo16" open-type="navigate">demo16</navigator>
<navigator url="/pages/demo15/demo15"
open-type="redirect">demo15</navigator>
<!-- view{$}*100 -->