小程序学习(下篇)

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语句可以导入外联样式表,只支持相对路径

实践

  1. 在文件中新建一个styles文件,之后建立common.wxss文件

    view{
    color: blueviolet;
    font-size: 100rpx;
    }
  2. 直接在页面所对应wxss文件中引用即可

    @import "../../styles/common.wxss";

7.3、选择器

在小程序的选择器与之前在css中的非常像,但是 特别注意

小程序不支持通配符 *.

选择器样例样例描述权重优先级
.class.intro选择所有拥有class=“intro”的组件10
elementview选择所有view组件1
#id#firstname选择拥有id=“firstname”的组件100
element,elementview,checkbox选择所有文档的view组件和所有的checkbox组件
nth-child(n)view:nth-child(n)选择某个索引的标签
::afterview::after在view组件后边插入内容
::beforeview::before在view组件前边插入内容
style1000
!important正无穷

7.4、小程序中使用less

原生小程序不支持less,某些小程序的框架大体都支持,如 wepy,mpvue,taro等。但是仅仅因为一个less功能,而去引用一个框架,肯定是不可取的,因此可以用以下方式来实现

  1. 编辑器是vscode

  2. 安装插件 easy less

  3. 在vscode的设置中加入如下配置

    1. 点击左下角设置

    2. 点击右上角左1按钮

    3. 添加如下图第3、4行配置

  4. 在要编写样式的地方,新建less文件,如index.less,然后正常编辑即可。

实践

1、注意,在vscode中的css注释会跟着过去,而less不会

在less文件书写好样式之后,他会自动的转换成css结构。具体代码如下,左边是在vscode中编写的代码

2、尝试导入,如下图

8、常见组件

8.1、view标签 div

属性类型默认值必填说明最低版本
hover-classstringnone指定按下去的样式类。当 hover-class="none" 时,没有点击态效果1.0.0
hover-stop-propagationbooleanfalse指定是否阻止本节点的祖先节点出现点击态1.5.0
hover-start-timenumber50按住后多久出现点击态,单位毫秒1.0.0
hover-stay-timenumber400手指松开后点击态保留时间,单位毫秒1.0.0

8.2、text 类似 span

  1. 文本标签

  2. 只能嵌套text

  3. 长按文字可以复制(只有该标签有这个功能)

  4. 可以对 空格 进行编码

    属性名类型默认值说明
    selectableBooleanfalse文本是否可选
    decodeBooleanfalse是否解析

实战

<text selectable decode>abc长按文字复制
&nbsp;&nbsp;&nbsp;123&nbsp; &lt; &gt; &amp; &apos; &ensp; &emsp;</text>

解析:直接写上属性就行,可以不用赋值,当然,也可以和下面代码一样写

<text selectable="{{true}}" decode="{{true}}">
未晞&nbsp;&amp;
</tex

8.3、image

这个与之前的很不一样

  1. 图片标签,image组件默认宽度为320px,高度为240px

  2. 支持懒加载

属性名类型默认值说明
srcString图片资源地址
modeString‘scaleToFill’图片裁剪、缩放的模式
lazy-loadBooleanfalse图片懒加载

统一使用外网图片链接。

推荐使用

土豆图床[图床 - 免费图片外链 (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-dotsbooleanfalse是否显示面板指示点1.0.0
indicator-colorcolorrgba(0, 0, 0, .3)指示点颜色1.1.0
indicator-active-colorcolor#000000当前选中的指示点颜色1.1.0
autoplaybooleanfalse是否自动切换1.0.0
currentnumber0当前所在滑块的 index1.0.0
circularbooleanfalse是否采用衔接滑动1.0.0
intervalnumber5000自动切换时间间隔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

  • 块级元素默认 会换行 可以直接加宽度与高度

  • 要跳转的页面路径,既可以是绝对路径也可以是相对路径

属性说明

属性类型默认值必填说明最低版本
targetstringself在哪个目标上发生跳转,默认当前小程序。可选值:self/miniProgram2.0.7
urlstring当前小程序内的跳转链接1.0.0
open-typestringnavigate跳转方式。1.0.0
deltanumber1当 open-type 为 'navigateBack' 时有效,表示回退的层数1.0.0
app-idstringtarget="miniProgram"open-type="navigate"时有效,要打开的小程序 appId2.0.7
pathstringtarget="miniProgram"open-type="navigate"时有效,打开的页面路径,如果为空则打开首页2.0.7
extra-dataobjecttarget="miniProgram"open-type="navigate/navigateBack"时有效,需要传递给目标小程序的数据,目标小程序可在 App.onLaunch()App.onShow() 中获取到这份数据。详情2.0.7
versionstringreleasetarget="miniProgram"open-type="navigate"时有效,要打开的小程序版本2.0.7
short-linkstringtarget="miniProgram"时有效,当传递该参数后,可以不传 app-id 和 path。链接可以通过【小程序菜单】->【复制链接】获取。2.18.1
hover-classstringnavigator-hover指定点击时的样式类,当hover-class="none"时,没有点击态效果1.0.0
hover-stop-propagationbooleanfalse指定是否阻止本节点的祖先节点出现点击态1.5.0
hover-start-timenumber50按住后多久出现点击态,单位毫秒1.0.0
hover-stay-timenumber600手指松开后点击态保留时间,单位毫秒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

  1. tip: nodes 不推荐使用 String 类型,性能会有所下降。

  2. tip: rich-text 组件内屏蔽所有节点的事件。

  3. tip: attrs 属性不支持 id ,支持 class 。

  4. tip: name 属性大小写不敏感。

  5. tip: 如果使用了不受信任的 HTML 节点,该节点及其所有子节点将会被移除。

  6. tip: img 标签仅支持网络图片。

  7. tip: 如果在自定义组件中使用 rich-text 组件,那么仅自定义组件的 wxss 样式对 rich-text 中的 class 生效。

8.7、button

8.7.1、外观属性

属性类型默认值必填说明最低版本
sizestringdefault按钮的大小1.0.0
default默认大小 mini小尺寸
typestringdefault按钮的样式类型1.0.0
合法值说明:primary绿色 default白色 warn红色
plainbooleanfalse按钮是否镂空,背景色透明1.0.0
disabledbooleanfalse是否禁用1.0.0
loadingbooleanfalse名称前是否带 loading 图标1.0.0
form-typestring用于 form 组件,点击分别会触发 form 组件的 submit/reset 事件1.0.0
合法值说明 submit提交表单reset重置表单
open-typestring微信开放能力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 的实现流程

  1. 将小程序的appid 由测试号 改为 自己的appid

  2. 登录微信小程序官网小程序 (qq.com),添加 客服-微信

  3. 为了方便演示,老师自己准备了两个账号 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

属性说明

属性类型默认值必填说明最低版本
typestringicon的类型,有效值:success, success_no_circle, info, warn, waiting, cancel, download, search, clear1.0.0
sizenumber/string23icon的大小,单位默认为px,2.4.0起支持传入单位(rpx/px),2.21.3起支持传入其余单位(rem 等)。1.0.0
colorstringicon的颜色,同 css 的color1.0.0

补充知识点 block标签

  1. <block/> 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。

  2. 因为 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

属性说明

属性类型默认值必填说明最低版本
valuestringradio 标识。当该radio 选中时,radio-group 的 change 事件会携带radio的value1.0.0
checkedbooleanfalse当前是否选中1.0.0
disabledbooleanfalse是否禁用1.0.0
colorstring#09BB07radio的颜色,同 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、应用生命周期

属性类型默认值必填说明
onLaunchfunction监听小程序初始化。
onShowfunction监听小程序启动或者切前台。
onHidefunction监听小程序切后台。
onErrorfunction错误监听函数。
onPageNotFoundfunction页面不存在监听函数。

实战

// 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 -->
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值