微信小程序笔记

微信小程序笔记

一.⼩程序配置⽂件

1.1全局配置app.json

app.json 是当前⼩程序的全局配置,包括了⼩程序的所有⻚⾯路径、界⾯表现、⽹络超时时间、底 部 tab 等。普通快速启动项⽬⾥边的 app.json 配置

{
  "pages":[
    "pages/index/index",//微信小程序显示的首页,谁在第一位显示谁
    "pages/logs/logs",
    "pages/demo01/demo01"
  ],
  "window":{
    "backgroundTextStyle":"light",
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "WeChat",
    "navigationBarTextStyle":"black"
  },
  "style": "v2",
  "sitemapLocation": "sitemap.json"
}

字段的含义 :

  1. pages 字段⸺⽤于描述当前⼩程序所有⻚⾯路径,这是为了让微信客⼾端知道当前你的⼩程序 ⻚⾯定义在哪个⽬录。

  2. window 字段⸺定义⼩程序所有⻚⾯的顶部背景颜⾊,⽂字颜⾊定义等。

  3. 完整的配置信息请参考 app.json配置

1.2全局window配置

{
  "pages":[
    "pages/index/index",//微信小程序显示的首页,谁在第一位显示谁
    "pages/logs/logs",
    "pages/demo01/demo01"
  ],
  "window":{
    "backgroundTextStyle":"dark",//两个值dark/light 默认是light
    "navigationBarBackgroundColor": "#0094ff",//头部导航栏颜色
    "navigationBarTitleText": "我的应用",//标题
    "navigationBarTextStyle":"white",//标题颜色,两个值black/white 默认是white
    "enablePullDownRefresh": true,//是否开启下拉刷新,默认是false
    "backgroundColor": "#ccc"//下拉刷新时的背景颜色
  },
    "tabBar": {//tabbar
    "color": "#999",//未选中的字体颜色
    "selectedColor": "#ff2d4a",//选中时字体颜色
    "backgroundColor": "#fafafa",//tabbar的背景颜色
    "position": "bottom",//tabbar的位置
    "borderStyle": "black",//tabbar边框
    "list": [
      {
        "pagePath": "pages/index/index",
        "text": "首页",
        "iconPath": "icons/home.png",
        "selectedIconPath": "icons/home-o.png"
      },
      {
        "pagePath": "pages/category/index",
        "text": "分类",
        "iconPath": "icons/category.png",
        "selectedIconPath": "icons/category-o.png"
      }
      ,
      {
        "pagePath": "pages/cart/index",
        "text": "购物车",
        "iconPath": "icons/cart.png",
        "selectedIconPath": "icons/cart-o.png"
      }
      ,
      {
        "pagePath": "pages/user/index",
        "text": "我的",
        "iconPath": "icons/my.png",
        "selectedIconPath": "icons/my-o.png"
      }
    ]
  }
  "style": "v2",
  "sitemapLocation": "sitemap.json"
}

二.数据绑定

<!--pages/demo02/demo02.wxml-->
<!-- <text></text>  相当于html中的span 是一个行内块元素,不换行 -->
<!-- <view></view> 相当于html中的div 是一个块级元素 换行 -->
<!-- <checkbox></checkbox> 相当于html中的复选框 -->
<text>1</text>
<text>2</text>
<view>1</view>
<view>2</view>
<!-- 1.字符串类型 -->
<view>
    {{msg}}
</view>
<!-- 2.数字类型 -->
<view>{{num}}</view>
<!-- 3.bool类型 -->
<view>是否是伪娘:{{isGril}}</view>
<!-- 4.object类型 -->
<view>{{person.name}}</view>
<view>{{person.age}}</view>
<view>{{person.height}}</view>
<view>{{person.weight}}</view>

<!-- 5.自定义属性   -->
<view data-num="{{num}}">自定义数据</view>

<!-- 6.使用bool充当checked属性是要注意 -->
<!-- checked="{{isChecked}}" 前一个双引号和花括号直接不能有空格否则机会编译错误 
    以下写法就是错误的示范
    <checkbox checked="        {{isChecked}}"></checkbox>
-->
<checkbox checked="{{isChecked}}"></checkbox>

<!-- 7.运算=>表达式
    可以在花括号中放一些运算表达式,但是不能放语句
    例:<view>{{1+1}}</view>成立
    <view>{{if()}}</view> 这样不允许
 -->
 <!-- 数字加减 -->
<view>{{1+1 - 3  * 2 / 3}}</view>
  
<!-- 字符串拼接 -->
<view>{{'hello' + 'wx'}}</view>

<!-- 三元表达式 -->
<view>{{17+1 == 18 ? '欢迎' : '您未满18岁'}}</view>

<!-- 这样是不允许的 <view>{{if(age>18){666}}}</view> -->

 //注意: 花括号和引号之间如果有空格,将最终被解析成为字符串

2.1循环

wx:for

项的变量名默认为 item wx:for–item 可以指定数组当前元素的变量名

下标变量名默认为 index wx:for–index 可以指定数组当前下标的变量名

wx:key ⽤来提⾼数组渲染的性能

wx:key 绑定的值 有如下选择

  1. string 类型,表⽰ 循环项中的唯⼀属性 如
list:[{id:0,name:"炒饭"},{id:1,name:"炒面"}]

wx:key="id"

2.保留字 *this ,它的意思是 item 本⾝ ,*this 代表的必须是 唯⼀的字符串和数组。

list:[1,2,3,4,5]
wx:key="*this"
<!-- 循环
    1 wx:for="{{数组或者对象}}"  wx:for-item="循环项的名称"  wx:for-index="循环项的索引"
    2 wx:key="唯一的值" 用来提高列表渲染的性能
      1 wx:key 绑定一个普通的字符串的时候 那么这个字符串名称 肯定是 循环数组 中的 对象的 唯一属性
      2 wx:key ="*this"  就表示 你的数组 是一个普通的数组  *this 表示是 循环项 
        [1,2,3,44,5]
        ["1","222","adfdf"]
    3 当出现 数组的嵌套循环的时候 尤其要注意  以下绑定的名称 不要重名
        wx:for-item="item" wx:for-index="index"
    4 默认情况下 我们 不写
       wx:for-item="item" wx:for-index="index"
       小程序也会把 循环项的名称 和 索引的名称 item 和 index 
       只有一层循环的话 (wx:for-item="item" wx:for-index="index") 可以省略
 -->
 <view wx:for="{{list}}" wx:for-item="item" wx:for-index="index" wx:key="id">
    索引:{{index}}---值:{{item.name}}
 </view>

 <view>遍历对象</view>
 <view wx:for="{{person}}" wx:for-item = "value" wx:for-index = "key" wx:key="age">
    属性:{{key}}---值:{{value}}
 </view>

2.2 block

渲染⼀个包含多节点的结构块 block最终不会变成真正的dom元素

<block wx:for="{{[1, 2, 3]}}" wx:key="*this" >
  <view> {{index}}: </view>
  <view> {{item}} </view>
</block>

2.3 if 条件渲染

在框架中,使⽤ wx:if="{{condition}}" 来判断是否需要渲染该代码块:

<!-- 10条件渲染
   1.wx:if="{{true/false}}"

   2.多分支
   wx:if="{{true/false}}"
   wx:elif="{{true/false}}"
   wx:else

   3.hidden
      1 在标签上直接加入属性 hidden 
      2 hidden="{{true/false}}"

   4. 什么场景下用哪个
      1 当标签不是频繁的切换显示 优先使用 wx:if
         直接把标签从 页面结构给移除掉 
      2 当标签频繁的切换显示的时候 优先使用 hidden
         通过添加样式的方式来切换显示 
         hidden 属性 不要和 样式 display一起使用
   
 -->

 <view>条件渲染</view>
 <view wx:if="{{true}}">显示</view>
 <view wx:if="{{false}}">隐藏</view>

 <view wx:if="{{false}}">不显示</view>
 <view wx:elif="{{false}}">不显示</view>
 <view wx:else>他们都不要,我接盘</view>

 <view>----------</view>
 <view hidden> 我被hidden我不会显示</view>
 <view hidden="{{false}}">我可以被看到</view>
 <view hidden="{{true}}">你看不到我</view>

2.4 小程序事件的绑定

小程序绑定事件,通过bind关键字来实现,如 bindtap bindinput bindchange等不同组件支持不同的事件,具体看组件的说明即可

<!-- 
  1.需要input标签绑定input事件
  绑定关键字 bindinput

  2.获取输入的值
  要通过事件源对象来获取
  e.detail.value

  3.把输入框的值 赋给data中的num
  注意:
  不能直接赋值
  this.num = e.detail.value
  this.data.num = e.detail.value
  真确的写法
  this.setData({
    num:e.detail.value
  })

  4.加入一个点击事件
    1.bindtap
    2.无法在小程序当中的事件中直接传参
    3.通过自定义属性的方式来传递参数
    4.事件源中获取自定义属性
    e.target.dataset.operation
注意:事件传参要通过自定义参数
   -->
<input type="text" bindinput="handleInput"></input>
<view>{{num}}</view>

<button bindtap="changeNum" data-operation="{{1}}">+</button>
<button bindtap="changeNum" data-operation="{{-1}}">-</button>

// pages/demo03/demo03.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    num: 0
  },
  handleInput(e) {
    console.log(e.detail.value)
    this.setData({
      num: e.detail.value
    })
  },
  changeNum(e){
    console.log(e)
    const {operation} = e.target.dataset
    this.setData({
      num:this.data.num + operation
    })
  }
})


2.5wxss宽度自适应配置

/* pages/demo04/demo04.wxss */
/*
1.小程序中 不需要主动引入样式文件
2.需要把页面中某些元素的单位 由px改换成rpx
    1.设计稿 750px
    750 px = 750rpx
      1 px = 1 rpx
    2.把屏幕宽度改成375px
    375px = 750 rpx
    1 px = 1 rpx 
    1rpx = 0.5px
    3.存在一个设计稿 款多 414 或者未知page
    1.设计稿 page 存在一个元素宽度 100px
    2.拿以上的需求 趋势线 不同宽度的页面适配

    page px = 750px
    1px = 750 rpx * 100 / page
    100px = 750 rpx * 100  / page
    假设设计稿的宽度page等于375px
    4. 利用 一个calc属性 
    注意:1.750和rpx中间不要留空格
    2.运算符的两边也不要留空格
*/
view{
  /* width: 200rpx; */
  height: 200rpx;
  background-color: aqua;
  font-size: 40rpx;
  width: calc(750rpx * 100 / 375);
}

2.6引入外部样式

通过@import “路径位置”

注意只支持相对路径

代码演示:

/*style文件夹下的common样式*/
view{
  color: aqua;
  font-size: 16px;
}

/*导入到demo05中的样式中*/

@import "../../style/common.wxss"

2.7选择器

特别需要注意的是小程序不支持通配符*因此以下代码无效

*{
    margin:0;
    padding:0;
    box-sizing:border-box; 
 }

目前的选择器有:

选择器样例样例描述
.class.banner选择所有拥有class="banner"的组件
#id#phone选择拥有id="phone"的组件
elementview选择所有view组件
element,elementview,checkbox选择view和checkbox组件
nth-child(n)view:nth-child(n)选择某个标签
::afterview::after在view组件后面插入内容
::beforeview::before在view组件前边插入内容

2.8小程序中使用less

1.原生小程序不支持less,其他基于小程序的框架大体都支持,如wepy mpvue, taro

2.用vscode中的插件easy less

3.在vscode中设置加入以下配置

less.compile": {
        "outExt":       ".wxss"
   }

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

//嵌套写法
view{
    text{
        width: 20px;
    }
}
//定义变量
@color:yellow;
text{
    color: @color;
}
//导入外部less文件
@import '../../style/index.less';
view{
    color: @themeColor;
}

三.小程序常见的组件

重点讲解⼩程序中常⽤的布局组件

view, text, rich-text, button, image, navigator, icon, swiper, radio, checkbox 等

3.1 view

代替原来的div标签

 <view hover-class="h-class">
 点击我试试
 </view>

3.2 text

1.文本标签

2.只能嵌套text

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

4.可以对空格回车进行编辑

属性名类型默认值说明
selectableBooleanfalse文本是否可选
decodeBooleanfalse是否解码
<!--pages/demo07/demo07.wxml-->
<!-- selectable 是否可复制 decode是否解码 -->
<text selectable="{{true}}" decode="{{true}}">
我是一个text,我可以被复制 &nbsp; 123&lt;
</text>

3.3 image

<!--pages/demo08/demo08.wxml-->


<!-- 
image 图片标签
  1 src 指定要加载的图片的路径
    图片存在默认的宽度和高度 320 * 240      原图大小是 200 * 100
  2 mode 决定 图片内容 如何 和 图片标签 宽高 做适配
    1 scaleToFill 默认值 不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素 
    2 aspectFit 保持宽高比 确保图片的长边 显示出来   页面轮播图 常用
    3 aspectFill 保持纵横比缩放图片,只保证图片的 短 边能完全显示出来。  少用
    4 widthFix 以前web的图片的 宽度指定了之后 高度 会自己按比例来调整   常用  
    5 bottom。。 类似以前的backgroud-position 
  3 小程序当中的图片 直接就支持 懒加载  lazy-load
    1 lazy-load 会自己判断 当 图片 出现在 视口  上下 三屏的高度 之内的时候  自己开始加载图片 

 -->


<image mode="top" lazy-load  src="https://pic.images.ac.cn/image/5ea0fe288244e.html" >
    
</image>

1.image图片标签默认高度320px,240px

2.支持懒加载

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

mode有效值:

mode有13种模式,其中4种是缩放模式,9中是裁剪模式

模式说明
缩放scaleToFill不保持纵横比缩放图片,使图片的宽高完全拉伸至填满image元素
缩放aspectFilt保持纵横比缩放图片,是图片的长边能完全显示出来
缩放aspectFill保持纵横比缩放图片,只保证图片的短边能完全显示出来
缩放widthFix宽度不变,⾼度⾃动变化,保持原图宽⾼⽐不变
缩放top不缩放图⽚,只显⽰图⽚的顶部区域
缩放bottom不缩放图⽚,只显⽰图⽚的底部区域
缩放center不缩放图⽚,只显⽰图⽚的中间区域
缩放left不缩放图⽚,只显⽰图⽚的左边区域
缩放right不缩放图⽚,只显⽰图⽚的右边区域
缩放top left不缩放图⽚,只显⽰图⽚的左上边区域
缩放top right不缩放图⽚,只显⽰图⽚的右上边区域
缩放bottom left不缩放图⽚,只显⽰图⽚的左下边区域
缩放bottom right不缩放图⽚,只显⽰图⽚的右下边区域

3.4 swiper 微信内置轮播图组件

swiper组件默认的宽是100%,高度是150px

属性名类型默认值说明
indicator-dotsBooleanfalse是否显示面板指示点
indicator-colorColorrgba(0,0,0.3)指示点颜色
indicator-active-colorColor#000000当前选中的指示点颜色
autoplayBooleanfalse是否自动切换
intervalNumber5000(毫秒)自动切换事件间隔
circularBooleanfalse是否循环轮播
3.4.1swiper 滑块视图容器
3.4.2swiper-item每个滑块

默认宽度和高度都是100%

<!-- pages/demo09/demo09.wxml -->

<!-- 
  1 轮播图外层容器 swiper
  2 每一个轮播项 swiper-item
  3 swiper标签 存在默认样式
    1 width 100%
    2 height 150px    image 存在默认宽度和高度 320 * 240 
    3 swiper 高度 无法实现由内容撑开 
  4 先找出来 原图的宽度和高度 等比例 给swiper 定 宽度和高度
    原图的宽度和高度  1125 * 352 px
    swiper  高度 / swiper 宽度 =  原图的高度  /  原图的宽度
    swiper  高度  =  swiper 宽度 *  原图的高度 / 原图的宽度
    height: 100vw * 352 /  1125
  5 autoplay 自动轮播
  6 interval 修改轮播时间
  7 circular 衔接轮播
  8 indicator-dots 显示 指示器 分页器 索引器 
  9 indicator-color 指示器的未选择的颜色 
  10 indicator-active-color 选中的时候的指示器的颜色 
 -->
<swiper autoplay="{{true}}" interval="2000" circular indicator-dots="{{true}}" indicator-color="skyblue" indicator-active-color="orange">
    <swiper-item>
        <image mode="widthFix" src="//gw.alicdn.com/imgextra/i1/44/O1CN013zKZP11CCByG5bAeF_!!44-0-lubanu.jpg"></image>
    </swiper-item>
    <swiper-item>
        <image mode="widthFix" src="//gw.alicdn.com/imgextra/i2/142/O1CN012xkybe1Cv4pztdLZm_!!142-0-lubanu.jpg"></image>
    </swiper-item>
    <swiper-item>
        <image mode="widthFix" src="//gw.alicdn.com/imgextra/i4/190/O1CN01fmyLv41DH3qg3rPgY_!!190-0-lubanu.jpg"></image>
    </swiper-item>
</swiper>

wxss文件
/* pages/demo09/demo09.wxss */
image{
    width: 100%;
}
swiper{
    width: 100%;
    height: calc(100vw * 352 / 1125);
}

3.5 navigator导航标签

<!--pages/demo11/demo11.wxml-->

<!--
    导航组件navigator 类似于html中的a标签
    注意:navigator是块级元素默认会换行 可以直接加宽度和高度
    参数
    1. url:要跳转的页面路径
    2. target 要跳转到当前的小程序 还是其他的小程序
        默认值是self 自己小程序的页面
        miniProgram 其他的小程序的页面
    3. open-type 跳转的方式
        1.navigate 默认值 保留当前页面,跳转到应用内的某个页面,但是不能跳转到tabbar页面
        2.redirect 关闭当前页面,跳转到应用内的某个页面,但是不允许跳转到tabbar页面
        3.switchTab 跳转到tabbar页面,并关闭其他所有非tabbar页面
        4.reLaunch 关闭所有页面,打开到应用内的某个页面
 -->


<navigator url="/pages/demo09/demo09">
    跳转到轮播图页面
</navigator>
<!-- 因为open-type默认值是navigate 不能跳转到tabbar,所以不会有反应 -->
<navigator url="/pages/index/index">
    跳转到tabbar页面(我是默认值,跳不了哈哈哈)
</navigator>
<navigator open-type="redirect" url="/pages/demo09/demo09">
    我是redirect重定向到别的页面
</navigator>
<navigator open-type="switchTab" url="/pages/index/index">
    switchTab直接跳转到 tabbar页面
</navigator>
<navigator open-type="reLaunch" url="/pages/index/index">
    我是relaunch我可以随便跳转
</navigator>

navigator 导航组件 类似于超链接组件

属性名类型默认值说明
targetStringself在哪个目标上发生跳转,默认当前小程序,可选值self/miniProgram
urlString当前小程序内的跳转连接
open-typeStringnavigate跳转方式

open-type有效值:

说明
navigate保留当前页面,跳转到应用内的某个页面,但是不能跳转到tabbar页面
redirect关闭当前页面,跳转到应用内的某个页面,但是不能跳转到tabbar页面
switchTab跳转到tabbar页面,关闭其他所有非tabbar页面
reLaunch关闭所有页面,打开到应用内的某个页面
navigateBack关闭当前页面,返回上一页面或多级页面,可通过getCurrentPages()获取当前的页面栈,决定需要返回几层
exit退出小程序,target="miniProgram"时生效

3.6 rich-text

富文本标签 类似于vue中的v-html

示例代码

<!--pages/demo12/demo12.wxml-->
<!-- <text>pages/demo12/demo12.wxml</text> -->


<!-- 
  rich-text 富文本标签
  1 nodes属性来实现
    1 接收标签字符串 
    2 接收对象数组 
 -->
<rich-text nodes="{{html}}">
    
</rich-text>

// pages/demo12/demo12.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    // 1. 标签字符串 最常用
    // html:'<div class="tpl-wrapper" data-tpl-id="m_h_v31icon_1" style="margin-top: -10px;"><div view-name="DFrameLayout" style="display: flex; overflow: hidden; height: 160px; width: 375px; place-self: flex-start; position: relative;"><div view-name="DView" style="display: flex; overflow: hidden; background-color: rgb(255, 255, 255); margin-top: 9px; height: 100%; width: 100%; top: 0px; left: 0px; position: absolute;"></div><div view-name="HImageView" style="display: flex; overflow: hidden; height: 100%; width: 100%; position: absolute;"><div style="width: 100%; height: 100%; background-image: url(&quot;https://gw.alicdn.com/tps/TB155AUPpXXXXajXVXXXXXXXXXX-1125-480.png_.webp&quot;); background-repeat: no-repeat; background-position: center center; background-size: contain;"></div></div><div view-name="DLinearLayout" aria-label="天猫" style="display: flex; overflow: hidden; width: 61px; height: 67px; margin-left: 10px; margin-top: 13px; -webkit-box-orient: vertical; flex-direction: column; top: 0px; left: 0px; position: absolute;"><div view-name="HGifView" style="display: flex; overflow: hidden; width: 61px; height: 48px;"><div style="width: 100%; height: 100%; background-repeat: no-repeat; background-position: center center; background-size: contain; background-image: url(&quot;https://gw.alicdn.com/tfs/TB1Wxi2trsrBKNjSZFpXXcXhFXa-183-144.png_.webp&quot;);"></div></div><div view-name="DTextView" style="display: inline-block; overflow: hidden; font-size: 11px; height: auto; margin-top: 5px; text-align: center; color: rgb(102, 102, 102); width: 61px; text-overflow: ellipsis; white-space: nowrap; line-height: 14px;">天猫</div></div><div view-name="DLinearLayout" aria-label="聚划算" style="display: flex; overflow: hidden; width: 61px; height: 67px; margin-left: 83.5px; margin-top: 13px; -webkit-box-orient: vertical; flex-direction: column; top: 0px; left: 0px; position: absolute;"><div view-name="HGifView" style="display: flex; overflow: hidden; width: 61px; height: 48px;"><div style="width: 100%; height: 100%; background-repeat: no-repeat; background-position: center center; background-size: contain; background-image: url(&quot;https://img.alicdn.com/tfs/TB10UHQaNjaK1RjSZKzXXXVwXXa-183-144.png?getAvatar=1_.webp&quot;);"></div></div><div view-name="DTextView" style="display: inline-block; overflow: hidden; font-size: 11px; height: auto; margin-top: 5px; text-align: center; color: rgb(102, 102, 102); width: 61px; text-overflow: ellipsis; white-space: nowrap; line-height: 14px;">聚划算</div></div><div view-name="DLinearLayout" aria-label="天猫国际" style="display: flex; overflow: hidden; width: 61px; height: 67px; margin-left: 157px; margin-top: 13px; -webkit-box-orient: vertical; flex-direction: column; top: 0px; left: 0px; position: absolute;"><div view-name="HGifView" style="display: flex; overflow: hidden; width: 61px; height: 48px;"><div style="width: 100%; height: 100%; background-repeat: no-repeat; background-position: center center; background-size: contain; background-image: url(&quot;https://gw.alicdn.com/tfs/TB11rTqtj7nBKNjSZLeXXbxCFXa-183-144.png?getAvatar=1_.webp&quot;);"></div></div><div view-name="DTextView" style="display: inline-block; overflow: hidden; font-size: 11px; height: auto; margin-top: 5px; text-align: center; color: rgb(102, 102, 102); width: 61px; text-overflow: ellipsis; white-space: nowrap; line-height: 14px;">天猫国际</div></div><div view-name="DLinearLayout" aria-label="外卖" style="display: flex; overflow: hidden; width: 61px; height: 67px; margin-left: 230.5px; margin-top: 13px; -webkit-box-orient: vertical; flex-direction: column; top: 0px; left: 0px; position: absolute;"><div view-name="HGifView" style="display: flex; overflow: hidden; width: 61px; height: 48px;"><div style="width: 100%; height: 100%; background-repeat: no-repeat; background-position: center center; background-size: contain; background-image: url(&quot;https://gw.alicdn.com/tps/TB1eXc7PFXXXXb4XpXXXXXXXXXX-183-144.png?getAvatar=1_.webp&quot;);"></div></div><div view-name="DTextView" style="display: inline-block; overflow: hidden; font-size: 11px; height: auto; margin-top: 5px; text-align: center; color: rgb(102, 102, 102); width: 61px; text-overflow: ellipsis; white-space: nowrap; line-height: 14px;">外卖</div></div><div view-name="DLinearLayout" aria-label="天猫超市" style="display: flex; overflow: hidden; width: 61px; height: 67px; margin-left: 304px; margin-top: 13px; -webkit-box-orient: vertical; flex-direction: column; top: 0px; left: 0px; position: absolute;"><div view-name="HGifView" style="display: flex; overflow: hidden; width: 61px; height: 48px;"><div style="width: 100%; height: 100%; background-repeat: no-repeat; background-position: center center; background-size: contain; background-image: url(&quot;https://gw.alicdn.com/tfs/TB1IKqDtpooBKNjSZFPXXXa2XXa-183-144.png_.webp&quot;);"></div></div><div view-name="DTextView" style="display: inline-block; overflow: hidden; font-size: 11px; height: auto; margin-top: 5px; text-align: center; color: rgb(102, 102, 102); width: 61px; text-overflow: ellipsis; white-space: nowrap; line-height: 14px;">天猫超市</div></div><div view-name="DLinearLayout" aria-label="充值中心" style="display: flex; overflow: hidden; width: 61px; height: 67px; margin-left: 10px; margin-top: 84px; -webkit-box-orient: vertical; flex-direction: column; top: 0px; left: 0px; position: absolute;"><div view-name="HGifView" style="display: flex; overflow: hidden; width: 61px; height: 48px;"><div style="width: 100%; height: 100%; background-repeat: no-repeat; background-position: center center; background-size: contain; background-image: url(&quot;https://gw.alicdn.com/tfs/TB1o0FLtyMnBKNjSZFoXXbOSFXa-183-144.png_.webp&quot;);"></div></div><div view-name="DTextView" style="display: inline-block; overflow: hidden; font-size: 11px; height: auto; margin-top: 5px; text-align: center; color: rgb(102, 102, 102); width: 61px; text-overflow: ellipsis; white-space: nowrap; line-height: 14px;">充值中心</div></div><div view-name="DLinearLayout" aria-label="飞猪旅行" style="display: flex; overflow: hidden; width: 61px; height: 67px; margin-left: 83.5px; margin-top: 84px; -webkit-box-orient: vertical; flex-direction: column; top: 0px; left: 0px; position: absolute;"><div view-name="HGifView" style="display: flex; overflow: hidden; width: 61px; height: 48px;"><div style="width: 100%; height: 100%; background-repeat: no-repeat; background-position: center center; background-size: contain; background-image: url(&quot;https://gw.alicdn.com/tfs/TB15nKhtpkoBKNjSZFEXXbrEVXa-183-144.png?getAvatar=1_.webp&quot;);"></div></div><div view-name="DTextView" style="display: inline-block; overflow: hidden; font-size: 11px; height: auto; margin-top: 5px; text-align: center; color: rgb(102, 102, 102); width: 61px; text-overflow: ellipsis; white-space: nowrap; line-height: 14px;">飞猪旅行</div></div><div view-name="DLinearLayout" aria-label="领金币" style="display: flex; overflow: hidden; width: 61px; height: 67px; margin-left: 157px; margin-top: 84px; -webkit-box-orient: vertical; flex-direction: column; top: 0px; left: 0px; position: absolute;"><div view-name="HGifView" style="display: flex; overflow: hidden; width: 61px; height: 48px;"><div style="width: 100%; height: 100%; background-repeat: no-repeat; background-position: center center; background-size: contain; background-image: url(&quot;https://gw.alicdn.com/tfs/TB1BqystrZnBKNjSZFrXXaRLFXa-183-144.png?getAvatar=1_.webp&quot;);"></div></div><div view-name="DTextView" style="display: inline-block; overflow: hidden; font-size: 11px; height: auto; margin-top: 5px; text-align: center; color: rgb(102, 102, 102); width: 61px; text-overflow: ellipsis; white-space: nowrap; line-height: 14px;">领金币</div></div><div view-name="DLinearLayout" aria-label="拍卖" style="display: flex; overflow: hidden; width: 61px; height: 67px; margin-left: 230.5px; margin-top: 84px; -webkit-box-orient: vertical; flex-direction: column; top: 0px; left: 0px; position: absolute;"><div view-name="HGifView" style="display: flex; overflow: hidden; width: 61px; height: 48px;"><div style="width: 100%; height: 100%; background-repeat: no-repeat; background-position: center center; background-size: contain; background-image: url(&quot;https://gw.alicdn.com/tfs/TB1CMf4tlnTBKNjSZPfXXbf1XXa-183-144.png?getAvatar=1_.webp&quot;);"></div></div><div view-name="DTextView" style="display: inline-block; overflow: hidden; font-size: 11px; height: auto; margin-top: 5px; text-align: center; color: rgb(102, 102, 102); width: 61px; text-overflow: ellipsis; white-space: nowrap; line-height: 14px;">拍卖</div></div><div view-name="DLinearLayout" aria-label="分类" style="display: flex; overflow: hidden; width: 61px; height: 67px; margin-left: 304px; margin-top: 84px; -webkit-box-orient: vertical; flex-direction: column; top: 0px; left: 0px; position: absolute;"><div view-name="HGifView" style="display: flex; overflow: hidden; width: 61px; height: 48px;"><div style="width: 100%; height: 100%; background-repeat: no-repeat; background-position: center center; background-size: contain; background-image: url(&quot;https://gw.alicdn.com/tfs/TB18P98tyQnBKNjSZFmXXcApVXa-183-144.png?getAvatar=1_.webp&quot;);"></div></div><div view-name="DTextView" style="display: inline-block; overflow: hidden; font-size: 11px; height: auto; margin-top: 5px; text-align: center; color: rgb(102, 102, 102); width: 61px; text-overflow: ellipsis; white-space: nowrap; line-height: 14px;">分类</div></div></div></div>'
    //2.对象数组的方式
    html:[
      {
        //1.放一个div标签用name属性来指定
        name:'div',
        //2.标签上有哪些属性,用attrs来指定
        attrs:{
          //标签上的属性有类名,和样式
          class:'my_div',
          style:'color:red;'
        },
        //子节点用 children来指定
        children:[
          {
            //div里面的子节点p标签
            name:"p",
            //p身上的属性
            attrs:{
              
            },
            children:[
              {
                type:'text',
                text:'hello'
              }
            ]
          }
        ]
      }
    ]
  },
  
})

3.6.1nodes属性

nodes属性支持字符串和标签节点数组

属性说明类型必填备注
name标签String支持部分受信任的html节点
attrs属性object支持部分受信任的属性,遵循Pascal命名法
children子节点列表array结果和nodes一致

文本节点:type=text

属性说明类型必填备注
text文本String支持entities
html:[
      {
        //1.放一个div标签用name属性来指定
        name:'div',
        //2.标签上有哪些属性,用attrs来指定
        attrs:{
          //标签上的属性有类名,和样式
          class:'my_div',
          style:'color:red;'
        },
        //子节点用 children来指定
        children:[
          {
            //div里面的子节点p标签
            name:"p",
            //p身上的属性
            attrs:{
              
            },
            children:[
              {
                type:'text',
                text:'hello'
              }
            ]
          }
        ]
      }
    ]

3.7 button 组件

<!-- pages/demo13/demo13.wxml -->
<!-- <text>pages/demo13/demo13.wxml</text> -->
<!-- button按钮标签
    1外观的属性
        1.1 size控制按钮的大小
            默认值是default 
            mini 小尺寸
    2.type用来控制按钮的颜色 有三种
        2.1default 默认颜色 灰色
        2.2 primary 绿色
        2.3 warn 红色
    3. plain 按钮是否镂空 背景色透明
    4. loading 文字前实现正在等待的图标 -->
<button>default按钮</button>
<button size="mini">mini按钮</button>
<button type="primary">primary按钮</button>
<button type="warn">warn按钮</button>
<button type="warn" plain>warn按钮 透明</button>
<button type="primary" loading>primary按钮</button>
<!-- 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 feedback 打开 小程序内置的 意见反馈页面 
    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>
属性类型默认值必填说明
sizestringdefault按钮大小
typestringdefault按钮的样式类型
plainbooleandefault按钮是否镂空,背景⾊透明
disabledbooleanfalse是否禁用
loadingbooleanfalse名称前是否带loading图标
form-typestring用于’'组件,点击分别会触发‘’组件的submit/reset事件
open-typestring微信开放能力

size合法值

说明
default默认大小
mini小尺寸

type的合法值

说明
primary绿色
default白色
warn红色

form-type的合法值

说明
submit提交表单
reset重置表单

open-type的合法值

说明
contact打开客服会话,如果⽤⼾在会话中点击消息卡⽚后返回⼩程序,可以从bindcontact 回调中获得具体信息
share触发⽤⼾转发,使⽤前建议先阅读
getPhoneNumber获取⽤⼾⼿机号,可以从bindgetphonenumber回调中获取到⽤⼾信息,
getUserInfo获取⽤⼾信息,可以从bindgetuserinfo回调中获取到⽤⼾信息
launchApp打开APP,可以通过app-parameter属性设定向APP传的参数
openSetting打开授权设置⻚
feedback打开“意⻅反馈”⻚⾯,⽤⼾可提交反馈内容并上传⽇志,开发者可以登 录⼩程序管理后台后进⼊左侧菜单“客服反馈”⻚⾯获取到反馈内容

open-type 的 contact的实现流程

  1. 将⼩程序 的 appid 由测试号改为 ⾃⼰的 appid

  2. 登录微信⼩程序官⽹,添加 客服客服 – 微信微信

  3. 为了⽅便演⽰,⽼师⾃⼰准备了两个账号

    1. 普通⽤⼾ A

    2. 客服-微信 B

  4. 就是⼲

3.8 icon

属性类型默认值必填说明
typestringicon的类型,有效值:success, success_no_circle, info, warn, waiting, cancel, download, search,clear
sizenumber/string23icon大小
colorstringicon的颜色,同css的color
<!--pages/demo14/demo14.wxml-->

<!-- 
    字体图标 icon
    1.type 类型:string icon的类型,有效值:success, success_no_circle, info, warn, waiting, cancel, download, search,clear
    2.size 类型:number/string 默认值:23 
    3.color 类型string icon的颜色,同css的color
-->

<icon  type="success" size="60" color="#0094ff">
    
</icon>

3.9 radio

可以通过 color属性来修改颜色

需要搭配 radio-group ⼀起使⽤

<!-- pages/demo15/demo15.wxml -->
<!-- <text>pages/demo15/demo15.wxml</text> -->
<radio-group bindchange="checked">
    <radio color="aqua" value="male"></radio>
    <radio color="aqua" value="female"></radio>
</radio-group>
<view>选中了:{{res}}</view>

3.10 checkbox

可以通过 color属性来修改颜色

需要搭配 checkbox-group ⼀起使⽤

<!--pages/demo16/demo16.wxml-->
<!-- <text>pages/demo16/demo16.wxml</text> -->

<checkbox-group bindchange="checked">
    <checkbox value="{{item.value}}" wx:for="{{list}}" wx:key="{{item.id}}">
        {{item.name}}
    </checkbox>
</checkbox-group>
<view>
    勾选了:{{fruit}}
</view>
  

// pages/demo16/demo16.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    list:[
      {
        id:0,
        name:'🍎',
        value:'apple'
      },{
        id:1,
        name:'🍇',
        value:'grape'
      },{
        id:2,
        name:'🍌',
        value:'banana'
      },
    ],
    fruit:[]
  },
  checked(e){
    console.log(e)
    const value = e.detail.value
    this.setData({
      fruit:value
    })
  }
 
})

四.自定义组件

4.1创建自定义组件的步骤

  • 创建自定义组件文件夹

    类似于页面,一个自定义组件由 json ,wxml ,wxss ,js4个文件组成可以在微信开发者⼯具中快速创建组件的⽂件结构

  • 声明组件 ⾸先需要在组件的 json ⽂件中进⾏⾃定义组件声明

    {
      "component": true
    }
    
  • 编辑组件

    同时,还要在组件的 wxml ⽂件中编写组件模板,在 wxss ⽂件中加⼊组件样式slot 表⽰插槽,类似vue中的slot

    <!-- 这是自定义组件的内部WXML结构 -->
    <view class="inner">
     {{innerText}}
        <slot></slot>
    </view>
    

    在组件的 wxss ⽂件中编写样式

    注意:在组件wxss中不应使用ID选择器、属性选择器和标签名选择器。

    /* 这里的样式只应用于这个自定义组件 */
    .inner {
      color: red; 
    }
    
  • 注册组件

    在组件的 js ⽂件中,需要使⽤ Component() 来注册组件,并提供组件的属性定义、内部数据和 ⾃定义⽅法

    // components/Tabs/Tabs.js
    Component({
      /**
       * 组件的属性列表
       */
      properties: {
    
      },
    
      /**
       * 组件的初始数据
       */
      data: {
    
      },
    
      /**
       * 组件的方法列表
       */
      methods: {
    
      }
    })
    
    
  • 声明引⼊⾃定义组件

    ⾸先要在需要引用⻚⾯的 json ⽂件中进⾏引⽤声明。还要提供对应的组件名和组件路径

     // 引用声明
      "usingComponents": {
     // 要使用的组件的名称     // 组件的路径
        "my-header":"/components/myHeader/myHeader"
     }
    }
    
  • ⻚⾯中使⽤⾃定义组件

    <view>
      <!-- 以下是对一个自定义组件的引用 -->
      <my-header inner-text="Some text">
        <view>用来替代slot的</view>
        </my-header>
    </view>
    

4.2组件之间的传值

4.2.1父向子组件传值

类似于vue中的父向子组件传值,通过标签属性的方式来传递

子组件接收的形式,在子组件的js文件中的properties接收

  • 子组件js文件
// components/Tabs/Tabs.js
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    //父组件传递过来的List <Tabs list="{{list}}"></Tabs>
    list:{
      type:Array,
      value:[]
    }
  },

  /**
   * 组件的初始数据
   */
  data: {

  },
   /* 
  1 页面.js 文件中 存放事件回调函数的时候 存放在data同层级下!!!
  2 组件.js 文件中 存放事件回调函数的时候 必须要存在在 methods中!!!
   */
  /**
   * 组件的方法列表
   */
  methods: {
    changeTab(e){
      // console.log(e)
      // 1.获取当前索引
      const {index} = e.currentTarget.dataset
      console.log(index)
      //2. 获取data中的数组
      // 解构  对 复杂类型进行结构的时候 复制了一份 变量的引用而已
      // 最严谨的做法 重新拷贝一份 数组,再对这个数组的备份进行处理,
      // let tabs=JSON.parse(JSON.stringify(this.data.tabs));
      // 不要直接修改 this.data.数据 
      // let {tabs}=this.data;
      // let tabs=this.data;
      //循环数组
      let {list} = this.data
      list.forEach((item,i) => {
        if(i === index){
          item.isActive = true
        }else{
          item.isActive = false
        }
      });
      //重新赋值给list
      this.setData({
        list
      })
    }
  }
})

  • 子组件wxml文件
<!-- components/Tabs/Tabs.wxml -->
<!-- <text>components/Tabs/Tabs.wxml</text> -->
<view class="tabs">
    <view class="tabs_title">
        <view class="tabs_item {{item.isActive ? 'active':''}}" wx:for="{{list}}" wx:key="id" bindtap="changeTab" data-index="{{index}}">
            {{item.name}}
        </view>
    </view>
    <view class="tabs_connent">内容</view>
</view>
  • 子组件wxss文件
/* components/Tabs/Tabs.wxss */
.tabs_title{
    display: flex;
    padding: 10rpx;
}
.tabs_item{
    display: flex;
    flex:1;
    justify-content: center;
    align-items: center;
}
.active{
    border-bottom: 5px solid red;
    color: orange;
}
  • 父组件js文件
// pages/demo17/demo17.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    list: [{
        id: 0,
        name: '首页',
        isActive: true,
      }, {
        id: 1,
        name: '新闻',
        isActive: false,
      }, {
        id: 2,
        name: '娱乐',
        isActive: false,
      }, {
        id: 3,
        name: '金融',
        isActive: false,
      },

    ]
  },

  
})
  • 父组件wxml文件
 <!--pages/demo17/demo17.wxml-->
<!-- <text>pages/demo17/demo17.wxml</text> -->
<Tabs list="{{list}}"></Tabs>

 1 父组件(页面) 向子组件 传递数据 通过 标签属性的方式来传递
    1 在子组件上进行接收
    2 把这个数据当成是data中的数据直接用即可
  2 子向父传递数据 通过事件的方式传递
    1 在子组件的标签上加入一个 自定义事件
4.2.2子组件向父组件传值

类似vue 子传父用this.$emit(‘name’,value)

这里用this.triggerEvent(‘name’,value)

  • 子组件中的js
/*
	5 点击事件触发的时候 
      发父组件中的自定义事件 同时传递数据给  父组件  
      this.triggerEvent("父组件自定义事件的名称",要传递的参数)  
*/
//子组件向父组件传值
    changeTab(e){
      //获取当前的索引
      const {index} = e.currentTarget.dataset
      this.triggerEvent('myTabs',index)
        //第一参数是自定义事件名称,第一个参数是要传递的参数
    }
  • 父组件通过标签事件接收子组件传递的事件和参数
<Tabs list="{{list}}" aaa="123" bindmyTabs="changTabs"></Tabs>
这里绑定的事件myTabs就是子组件自定的事件名称
  • 父组件的js文件
// pages/demo17/demo17.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    list: [{
        id: 0,
        name: '首页',
        isActive: true,
      }, {
        id: 1,
        name: '新闻',
        isActive: false,
      }, {
        id: 2,
        name: '娱乐',
        isActive: false,
      }, {
        id: 3,
        name: '金融',
        isActive: false,
      },

    ]
  },
  changTabs(e){
      //获取子组件传递过的当前的index
    console.log(e)
    const index = e.detail
    //深拷贝data中的list数组
    let list = JSON.parse(JSON.stringify(this.data.list))
    //遍历数组,把当前的索引设置为选中状态,其他改为false
    list.forEach((item,i) => i===index ? item.isActive=true : item.isActive=false)
      //设置list
    this.setData({
      list
    })
  }
})
4.2.3 插槽的使用

和vue中的slot作用一样,就是一个占位符,也可以有默认值,

当给定了内容,slot的内容就会被覆盖

示例:

  • 子组件的wxml文件
<view class="tabs">
    <view class="tabs_title">
        <view class="tabs_item {{item.isActive ? 'active':''}}" wx:for="{{list}}" wx:key="id" bindtap="changeTab" data-index="{{index}}">
            {{item.name}}
        </view>
    </view>
    <view class="tabs_connent"><slot ></slot></view>
    
    <!-- 以上的slot就是一个插槽 -->
</view>
  • 父组件的wxml文件
<!-- pages/demo17/demo17.wxml -->
<!-- 1 父组件(页面) 向子组件 传递数据 通过 标签属性的方式来传递
    1 在子组件上进行接收
    2 把这个数据当成是data中的数据直接用即可
  2 子向父传递数据 通过事件的方式传递
    1 在子组件的标签上加入一个 自定义事件 -->
<Tabs list="{{list}}" aaa="123" bindmyTabs="changTabs">
    <block wx:if="{{list[0].isActive}}">首页</block>
    <block wx:elif="{{list[1].isActive}}">新闻</block>
    <block wx:elif="{{list[2].isActive}}">娱乐</block>
    <block wx:else>金融</block>
</Tabs>

4.3组件常见的属性

定义段类型是否必填描述
propertiesObject Map组件的对外属性,是属性名到属性设置的映射表,参见下文
dataObject组件内部数据,和properties一同用于组件模板渲染
observersObject组件数据字段监听器,用于properties和data的变化,类似于vue中的watch
methodsObject组件的方法,包括时间相应函数和任意的自定义方法,
createdFunction组件生命周期函数,在组件实例化刚刚被创建时执行,此时不能调用setData
attachedFunction组件⽣命周期函数,在组件实例进⼊⻚⾯节点树时执⾏,
readyFunction组件⽣命周期函数,在组件布局完成后执⾏,
movedFunction组件⽣命周期函数,在组件实例被移动到节点树另⼀个位置 时执⾏
detachedFunction组件⽣命周期函数,在组件实例被从⻚⾯节点树移除时执 行

五.小程序的生命周期函数

5.1应⽤⽣命周期

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

5.2页面生命周期

属性类型说明
dataObject页面的初始数据
onLoadfunction生命周期回调–监听页面加载
onShowfunction⽣命周期回调—监听⻚⾯显⽰
onReadyfunction⽣命周期回调—监听⻚⾯初次渲染完成
onHidefunction⽣命周期回调—监听⻚⾯隐藏
onUnloadfunction⽣命周期回调—监听⻚⾯卸载
oonPullDwonRefreshfunction监听用户下拉动作
onReachBottonfunction页面上拉触底事件的处理函数
onShareAppMessagefunction用户点击右上角转发
onPageScrollfunction页面滚动触发事件的处理函数
onResizefunction页面尺寸改时触发
onTabltemTapfunction当前是tab也时,点击tab时触发
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值