微信小程序基础

1. ⼩程序配置⽂件

⼀个⼩程序应⽤程序会包括最基本的两种配置⽂件。⼀种是全局的 app.json 和⻚⾯⾃⼰的 page.json

注意:配置文件中不能出现注释

1.1.全局配置app.json

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

在这里插入图片描述

字段的含义:

  1. pages 字段⸺⽤于描述当前⼩程序所有⻚⾯路径,这是为了让微信客⼾端知道当前你的⼩程序⻚⾯定义在哪个⽬录。
  2. window 字段⸺定义⼩程序所有⻚⾯的顶部背景颜⾊,⽂字颜⾊定义等。
  3. 完整的配置信息请参考app.json配置

1.1.1.tabbar

在这里插入图片描述

1.2.⻚⾯配置page.json

⻚⾯配置page.json

这⾥的 page.json 其实⽤来表⽰⻚⾯⽬录下的 page.json 这类和⼩程序⻚⾯相关的配置。

开发者可以独⽴定义每个⻚⾯的⼀些属性,如顶部颜⾊、是否允许下拉刷新等等。

⻚⾯的配置只能设置 app.json 中部分 window 配置项的内容,⻚⾯中配置项会覆盖 app.json的 window 中相同的配置项。

配置项
在这里插入图片描述

在这里插入图片描述

1.3.sitemap配置-了解即可

sitemap配置

⼩程序根⽬录下的 sitemap.json ⽂件⽤于配置⼩程序及其⻚⾯是否允许被微信索引。

2.模板语法

WXML(WeiXinMarkupLanguage)是框架设计的⼀套标签语⾔,结合基础组件事件系统,可以构建出⻚⾯的结构。

2.1.数据绑定

Page({
  /**
   * 页面的初始数据
   */
  data: {
    message: 'Hello MINA!',
    num: 10000,
    bol:false,
    person:{
      age:30,
      height:180,
      weight:160,
      name:"xiaoming"
    },
    isChecked:false
  }
})
<!-- 1 字符串 -->
<view> {{ message }} </view>
<!-- 2 数字类型 -->
<view> {{ num }} </view>
<!-- 3 bool类型 -->
<view> {{ bol }} </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-->
<!-- 字符串和花括号之间一定不要存在空格,否则会导致识别失败的 -->
<view>
<checkbox checked="{{isChecked}}"></checkbox>
</view>

在这里插入图片描述

2.2.运算

<!-- 
  7 运算 => 表达式
    1 可以在花括号中 加入 表达式 --  “语句”
    2 表达式
      指的是一些简单 运算 数字运算 字符串 拼接  逻辑运算。。
      1 数字的加减。。
      2 字符串拼接
      3 三元表达式 
    3 语句
      1 复杂的代码段
        1 if else
        2 switch
        3 do while 。。。。
        4 for 。。。
 -->
<view>{{1+1}}</view>
<view>{{'1'+'1'}}</view>
<view>{{ 11%2===0 ? '偶数' : '奇数' }}</view>
<view hidden="{{flag ? true : false}}"> Hidden </view>
<view> {{a + b}} + {{c}} + d </view>
<view>{{"hello " + name}}</view>
    name:"xiaoming2",
    a: 1,
    b: 2,
    c: 3,

在这里插入图片描述
花括号和引号之间如果有空格,将最终被解析成为字符串

2.3.列表渲染

<!-- 
  8 列表循环
    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") 可以省略

  9 对象循环
    1 wx:for="{{对象}}" wx:for-item="对象的值"  wx:for-index="对象的属性"
    2 循环对象的时候 最好把 item和index的名称都修改一下
      wx:for-item="value"  wx:for-index="key"

 -->

<view>
  <view wx:for="{{list}}" wx:for-item="item" 
  wx:for-index="index" wx:key="id">
    索引:{{index}} --:{{item.name}}
  </view>
</view>

<view>
  <view>对象循环</view>
  <view wx:for="{{person}}" wx:for-item="value" 
  wx:for-index="key" wx:key="age">
    属性:{{key}} --:{{value}}
  </view>
</view>
   person:{
      age:30,
      height:180,
      weight:160,
      name:"xiaoming"
    },
   list: [
      {
        id: 0,
        name: "猪八戒"
      },
      {
        id: 1,
        name: "天蓬元帅"
      },
      {
        id: 2,
        name: "悟能"
      }
    ]

在这里插入图片描述

<!-- 
   10 block
    1 占位符的标签 
    2 写代码的时候 可以看到这标签存在
    3 页面渲染 小程序会把它移除掉
  -->

<view>
  <block wx:for="{{list}}" wx:for-item="item" 
  wx:for-index="index" wx:key="id" class="my_list">
    索引:{{index}} --:{{item.name}}
  </block>
</view>

在这里插入图片描述

2.4.条件渲染

  <!-- 
    11 条件渲染
      1 wx:if="{{true/false}}"
        1 if , else , if else
        wx:if
        wx:elif
        wx:else 
      2 hidden 
        1 在标签上直接加入属性 hidden 
        2 hidden="{{true}}"

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

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

     <view wx:if="{{flase}}">1</view>
     <view wx:elif="{{flase}}">2 </view>
     <view wx:else> 3 </view>

     <view>---------------</view>
     <view hidden >hidden1</view>
     <view hidden="{{false}}" >hidden2</view>

     <view>-----000-------</view>
     <view wx:if="{{false}}">wx:if</view>
     <view hidden  style="display: flex;" >hidden</view>
   </view>

在这里插入图片描述

3. 事件绑定

⼩程序中绑定事件,通过bind关键字来实现。如 bindtap bindinput bindchange 等。

不同的组件⽀持不同的事件,具体看组件的说明即可。

<!-- 
  1 需要给input标签绑定 input事件 
    绑定关键字 bindinput
  2 如何获取 输入框的值 
    通过事件源对象来获取  
    e.detail.value 
  3 把输入框的值 赋值到 data当中
    不能直接 
      1 this.data.num=e.detail.value 
      2 this.num=e.detail.value 
    正确的写法
      this.setData({
        num:e.detail.value 
      })
  4 需要加入一个点击事件 
      1 bindtap
      2 无法在小程序当中的 事件中 直接传参 
      3 通过自定义属性的方式来传递参数
      4 事件源中获取 自定义属性
 -->
<input type="text" bindinput="handleInput" />
<button bindtap="handletap" data-operation="{{1}}" >+</button>
<button bindtap="handletap" data-operation="{{-1}}">-</button>
<view>  
  {{num}}
</view>
Page({
  data: {
    num: 0
  },
  // 输入框的input事件的执行逻辑
  handleInput(e) {
    console.log(e.detail.value );
    this.setData({
      num: e.detail.value
    })
  },
  // 加 减 按钮的事件
  handletap(e) {
    // console.log(e);
    // 1 获取自定义属性 operation
    const operation = e.currentTarget.dataset.operation;
    this.setData({
      num: this.data.num + operation
    })
  }
})

4. 样式WXSS

样式WXSS

WXSS (WeiXin Style Sheets)是一套样式语言,用于描述 WXML 的组件样式。

WXSS 用来决定 WXML 的组件应该怎么显示。

为了适应广大的前端开发者,WXSS 具有 CSS 大部分特性。同时为了更适合开发微信小程序,WXSS 对 CSS 进行了扩充以及修改。

与 CSS 相比,WXSS 扩展的特性有:

  • 尺寸单位
  • 样式导入

4.1. 尺寸单位

  • rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。

在这里插入图片描述
建议: 开发微信小程序时设计师可以用 iPhone6 作为视觉稿的标准。

注意: 在较小的屏幕上不可避免的会有一些毛刺,请在开发时尽量避免这种情况。

使⽤步骤:

  1. 确定设计稿宽度pageWidth
  2. 计算⽐例 750rpx = pageWidth px ,因此 1px=750rpx/pageWidth 。
  3. 在less⽂件中,只要把设计稿中的 px=> 750/pageWidth rpx 即可。

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

  page px = 750 rpx
  1 px = 750 rpx / page
  100 px = 750 rpx * 100 / page 
  假设  page =  375px
4 利用 一个属性 calc属性  css 和 wxss 都支持 一个属性
  1 750 和 rpx 中间不要留空格
  2 运算符的两边也不要留空格
 */

 view{
   /* width: 200rpx; */
   height: 200rpx;
   font-size: 40rpx;
   background-color: aqua;
  /* 以下代码写法是错误  */
  /*  width:750 rpx * 100 / 375 ;  */
  width:calc(750rpx * 100 / 375);
 }
<view>
  rpx
</view>

4.2. 样式导入

使用@import语句可以导入外联样式表,@import后跟需要导入的外联样式表的相对路径,用;表示语句结束。

示例代码:

新建styles目录,添加common.wxss,代码如下:

view{
  color: aqua;
  font-size: 40rpx;
}

在需要使用该样式的wxss中导入

/* 
1 引入的 代码 是通过 @import 来引入
2 路径 只能写相对路径
 */
 @import "../../styles/common.wxss";
<view>导入样式</view>

效果如下:
在这里插入图片描述

4.3. 选择器

目前支持的选择器有:
在这里插入图片描述

4.4.全局样式与局部样式

定义在 app.wxss 中的样式为全局样式,作用于每一个页面。在 page 的 wxss 文件中定义的样式为局部样式,只作用在对应的页面,并会覆盖 app.wxss 中相同的选择器。

4.5.⼩程序中使⽤less

原⽣⼩程序不⽀持 less ,其他基于⼩程序的框架⼤体都⽀持,如 wepy , mpvue , taro 等。
但是仅仅因为⼀个less功能,⽽去引⼊⼀个框架,肯定是不可取的。因此可以⽤以下⽅式来实现

  1. 编辑器是 vscode
  2. 安装插件 easy less
  3. 在vscode的设置中加⼊如下,配置
    在这里插入图片描述
  4. 在要编写样式的地⽅,新建 less ⽂件,如 index.less ,然后正常编辑即可。

5.常⻅组件

组件

重点讲解⼩程序中常⽤的布局组件
view,text,rich-text,button,image,navigator,icon,swiper,radio,checkbox 。

5.1.view 视图容器

在这里插入图片描述
代替原来的div 标签

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

5.2.text 文本

text 文本
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  1. ⽂本标签
  2. 只能嵌套text
  3. ⻓按⽂字可以复制(只有该标签有这个功能)
  4. 可以对空格回⻋进⾏编码
<!-- 
  1 长按文字复制 selectable
  2 对文本内容 进行 解码
 -->
<text selectable decode>
  text &nbsp; 123 &lt;
</text>

显示效果:
在这里插入图片描述

5.3.image 图片

image

图片。支持JPG、PNG、SVG、WEBP格式,2.3.0 起支持云文件ID。
在这里插入图片描述

mode 的合法值

mode有13种模式,其中4种是缩放模式,9种是裁剪模式。
在这里插入图片描述

  1. 图⽚标签,image组件默认宽度320px、⾼度240px
  2. ⽀持懒加载
  3. image组件中二维码/小程序码图片不支持长按识别。仅在wx.previewImage中支持长按识别

<!-- 
  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="bottom" lazy-load src="https://tva2.sinaimg.cn/large/007DFXDhgy1g51jlzfb4lj305k02s0sp.jpg" />
   
image{
  box-sizing: border-box;
  border: 1px solid red;
  width: 300px;
  height: 200px;
}

5.4.swiper

swiper

微信内置轮播图组件

<!-- 
  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 interval="1000" circular indicator-dots indicator-color="#0094ff" indicator-active-color="#ff0094">
    <swiper-item> <image mode="widthFix" src="//gw.alicdn.com/imgextra/i1/44/O1CN013zKZP11CCByG5bAeF_!!44-0-lubanu.jpg" /> </swiper-item>
    <swiper-item> <image mode="widthFix" src="//aecpm.alicdn.com/simba/img/TB1CWf9KpXXXXbuXpXXSutbFXXX.jpg_q50.jpg" /> </swiper-item>
    <swiper-item> <image mode="widthFix" src="//gw.alicdn.com/imgextra/i2/37/O1CN01syHZxs1C8zCFJj97b_!!37-0-lubanu.jpg" /> </swiper-item>
</swiper>

swiper {
  width: 100%;
  /* height: calc(100vw * 352 /  1125); */
  height: 31.28vw;
}
image {
  width: 100%;
}

在这里插入图片描述

5.5.navigator 页面链接

navigator

导航组件 类似超链接标签

在这里插入图片描述

open-type有效值:
在这里插入图片描述

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

 <navigator url="/pages/demo10/demo10"> 轮播图页面 </navigator>
 <navigator url="/pages/index/index"> 直接跳转到 tabbar页面 </navigator>
 <navigator open-type="redirect" url="/pages/demo10/demo10">  轮播图页面 redirect </navigator>
 <navigator open-type="switchTab" url="/pages/index/index">  switchTab直接跳转到 tabbar页面 </navigator>
 <navigator open-type="reLaunch" url="/pages/index/index">  reLaunch 可以随便跳 </navigator> 

5.6.rich-text 富文本标签

rich-text

可以将字符串解析成对应标签,类似vue中 v-html 功能

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

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: {
          // 标签上的属性 class  style
          class: "my_div",
          style: "color:red;"
        },
        // 3 子节点 children 要接收的数据类型和 nodes第二种渲染方式的数据类型一致 
        children: [
          {
            name: "p",
            attrs: {},
            // 放文本
            children: [
              {
                type: "text",
                text: "hello"
              }
            ]
          }
        ]
      }
    ]
  }
})

5.6.1.nodes属性

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

在这里插入图片描述
⽂本节点:type=text

在这里插入图片描述

  • nodes 不推荐使⽤ String 类型,性能会有所下降。
  • rich-text 组件内屏蔽所有节点的事件。
  • attrs 属性不⽀持id,⽀持class。
  • name 属性⼤⼩写不敏感。
  • 如果使⽤了不受信任的 HTML 节点,该节点及其所有⼦节点将会被移除。
  • img 标签仅⽀持⽹络图⽚。

5.7.button

button

在这里插入图片描述

size的合法值
在这里插入图片描述

type的合法值
在这里插入图片描述

form-type的合法值

在这里插入图片描述

open-type的合法值
在这里插入图片描述


<!-- 
  button 标签
  1 外观的属性
    1 size 控制按钮的大小
      1 default 默认大小
      2 mini 小尺寸
    2 type 用来控制按钮的颜色
      1 default 灰色
      2 primary 绿色
      3 warn 红色
    3 plain  按钮是否镂空,背景色透明
    4 loading 文字前显示正在等待图标
 -->
 <button>默认按钮</button>
 <button size="mini">  mini 默认按钮</button>
 <button type="primary"> primary 按钮</button> 
 <button type="warn"> warn 按钮</button> 
 <button type="warn" plain> plain 按钮</button> 
 <button type="primary" loading> loading 按钮</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>
Page({
  // 获取用户的手机号码信息
  getPhoneNumber(e) {
    console.log(e);
  },
  // 获取用户个人信息
  getUserInfo(e) {
    console.log(e);
  }
})

在这里插入图片描述

open-type的contact的实现流程

1. 将⼩程序的 appid 由测试号改为⾃⼰的 appid
2. 登录微信⼩程序官⽹,添加 客服 客服 - - 微信 微信
3. 为了⽅便演⽰,准备两个账号

  • 1.普通⽤⼾A
  • 2.客服-微信B

5.8.icon 图标

icon

图标。组件属性的长度单位默认为px,2.4.0起支持传入单位(rpx/px)。
在这里插入图片描述

<!-- 
  小程序中的字体图标
  1 type 图标的类型
    success|success_no_circle|info|warn|waiting|cancel|download|search|clear
  2 size 大小 
  3 color 图标的颜色
 -->
<icon type="cancel" size="60" color="#0094ff"> </icon>

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

<view class="group">
  <block wx:for="{{iconSize}}">
    <icon type="success" size="{{item}}" />
  </block>
</view>
<view class="group">
  <block wx:for="{{iconType}}">
    <icon type="{{item}}" size="40" />
  </block>
</view>
<view class="group">
  <block wx:for="{{iconColor}}">
    <icon type="success" size="40" color="{{item}}" />
  </block>
</view>
Page({
  data: {
    iconSize: [20, 30, 40, 50, 60, 70],
    iconType: [
      'success', 'success_no_circle', 'info', 'warn', 'waiting', 'cancel',
      'download', 'search', 'clear'
    ],
    iconColor: [
      'red', 'orange', 'yellow', 'green', 'rgb(0,255,255)', 'blue', 'purple'
    ],
  }
})

在这里插入图片描述

5.9.radio 单选项目

radio

在这里插入图片描述

示例1:

<!-- 
  radio 单选框
  1 radio标签 必须要和 父元素 radio-group来使用
  2 value 选中的单选框的值 
  3 需要给 radio-group 绑定 change事件 
  4 需要在页面中显示 选中的值
 -->
 <radio-group bindchange="handleChange">
   <radio color="red" value="male"></radio>
   <radio color="red" value="female" ></radio>
 </radio-group>

 <view>您选中的是:{{gender}}</view>
   
Page({
  data: {
    gender: ""
  },
  handleChange(e) {
    // 1 获取单选框中的值
    let gender = e.detail.value;
    // 2 把值 赋值给 data中的数据
    this.setData({
      // gender:gender
      gender
    })
  }
})

在这里插入图片描述

示例2:

<view class="page">
    <view class="page__hd">
        <text class="page__title">radio</text>
        <text class="page__desc">单选框</text>
    </view>
    <view class="page__bd">
        <view class="section section_gap">
            <radio-group class="radio-group" bindchange="radioChange">
                <radio class="radio" wx:for-items="{{items}}"
                 wx:key="name" value="{{item.name}}" 
                 checked="{{item.checked}}">
                    <text>{{item.value}}</text>
                </radio>
            </radio-group>
        </view>
    </view>
</view>
Page({
  data: {
    items: [
      { name: 'USA', value: '美国' },
      { name: 'CHN', value: '中国', checked: 'true' },
      { name: 'BRA', value: '巴西' },
      { name: 'JPN', value: '日本' },
      { name: 'ENG', value: '英国' },
      { name: 'FRA', value: '法国' },
    ]
  },
  radioChange: function (e) {
    console.log('radio发生change事件,携带value值为:', e.detail.value)
  }
})

.radio-group {
    border-bottom: 1px solid #ddd;
}
.radio {
    display: block;
    border-top: 1px solid #ddd;
    padding: 5px;
}

在这里插入图片描述

5.10.checkbox 多选项目

checkbox

在这里插入图片描述

<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/demo16/demo16.js
Page({
  data: {
    list: [
      {
        id: 0,
        name: "🍎",
        value: "apple"
      },
      {
        id: 1,
        name: "🍇",
        value: "grape"
      },
      {
        id: 2,
        name: "🍌",
        value: "bananer"
      }
    ],
    checkedList: []
  },
  // 复选框的选中事件
  handleItemChange(e) {
    // 1 获取被选中的复选框的值
    const checkedList = e.detail.value;
    // 2 进行赋值
    this.setData({
      checkedList
    })
  }
})

在这里插入图片描述


<checkbox-group bindchange="checkboxChange">
  <label class="checkbox" wx:for="{{items}}">
    <checkbox value="{{item.name}}" checked="{{item.checked}}"/>{{item.value}}
  </label>
</checkbox-group>
Page({
  data: {
    items: [
      { name: 'USA', value: '美国' },
      { name: 'CHN', value: '中国', checked: 'true' },
      { name: 'BRA', value: '巴西' },
      { name: 'JPN', value: '日本' },
      { name: 'ENG', value: '英国' },
      { name: 'TUR', value: '法国' },
    ]
  },
  checkboxChange: function (e) {
    console.log('checkbox发生change事件,携带value值为:', e.detail.value)
  }
})
.intro {
  margin: 30px;
  text-align: center;
}

在这里插入图片描述


6.⾃定义组件

自定义组件

类似vue或者react中的自定义组件

⼩程序允许我们使⽤⾃定义组件的⽅式来构建⻚⾯。

6.1.创建⾃定义组件

⾃定义组件

开发者可以将页面内的功能模块抽象成自定义组件,以便在不同的页面中重复使用;也可以将复杂的页面拆分成多个低耦合的模块,有助于代码维护。自定义组件在使用时与基础组件非常相似。

类似于页面,一个自定义组件由 json wxml wxss js 4个文件组成。要编写一个自定义组件,首先需要在 json 文件中进行自定义组件声明(将 component 字段设为 true 可将这一组文件设为自定义组件):

{
  "component": true
}

可以在微信开发者⼯具中快速创建组件的⽂件结构

新建components目录,并在components目录下新建Tabs目录,右键新建 名为Tabs的Component。

在这里插入图片描述
创建后如下:
在这里插入图片描述
在Tabs.js和Tabs.json中自动生成了如下代码:

// components/Tabs/Tabs.js
Component({
  /**
   * 组件的属性列表
   */
  properties: {

  },

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

  },

  /**
   * 组件的方法列表
   */
  methods: {

  }
})

{
  "component": true,
  "usingComponents": {}
}

接下来在我们的demo.json中导入组定义组件:

{
  "usingComponents": {
    "Tabs": "../../components/Tabs/Tabs"
  }
}

在demo.wxml中使用自定义Tabs组件

<Tabs></Tabs>

结果显示了我们自定义Tabs组件的内容:
在这里插入图片描述

示例 -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>
</view>

Tabs.wxss:

.tabs {
}

.tabs_title {
  display: flex;
  padding: 10rpx;
}

.title_item {
  flex: 1;
  display: flex;
  justify-content: center;
  align-items: center;
}

.active {
  color: red;
  border-bottom: 5rpx solid currentColor;
}

实现如下效果:
在这里插入图片描述


示例:Tabs的完整效果实现

需要实现⾃定义组件传参 :

  1. ⽗组件通过属性的⽅式给⼦组件传递参数
  2. ⼦组件通过事件的⽅式向⽗组件传递参数

Tabs.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>
</view> -->

<view class="tabs">
  <view class="tabs_title">
    <view wx:for="{{tabs}}" wx:key="id" 
    class="title_item {{item.isActive?'active':''}}" 
    bindtap="hanldeItemTap" data-index="{{index}}">
      {{item.name}}
    </view>
  </view>
  <view class="tabs_content">
    <!-- 
      slot 标签 其实就是一个占位符 插槽
      等到 父组件调用 子组件的时候 再传递 标签过来 最终 这些被传递的标签
      就会替换 slot 插槽的位置 
     -->
    <slot></slot>
  </view>
</view>

Tabs.js

// components/Tabs.js
Component({
  /**
   * 里面存放的是 要从父组件中接收的数据
   */
  properties: {
    // 要接收的数据的名称
    // aaa:{
    //   // type  要接收的数据的类型 
    //   type:String,
    //   // value  默认值
    //   value:""
    // }
    tabs: {
      type: Array,
      value: []
    }
  },

  /**
   * 组件的初始数据
   */
  data: {
    // tabs
  },
  /* 
  1 页面.js 文件中 存放事件回调函数的时候 存放在data同层级下!!!
  2 组件.js 文件中 存放事件回调函数的时候 必须要存在在 methods中!!!
   */


  methods: {
    hanldeItemTap(e) {
      /* 
      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;
      // 4 循环数组
      // [].forEach 遍历数组 遍历数组的时候 修改了 v ,也会导致源数组被修改
      // tabs.forEach((v,i)=>i===index?v.isActive=true:v.isActive=false);

      // this.setData({
      // tabs
      // })
    }
  }
})

demo.wxml

<!-- 
  1 父组件(页面) 向子组件 传递数据 通过 标签属性的方式来传递
    1 在子组件上进行接收
    2 把这个数据当成是data中的数据直接用即可
  2 子向父传递数据 通过事件的方式传递
    1 在子组件的标签上加入一个 自定义事件
  
 -->
<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>
 
</Tabs>

demo.js

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) {
    // 接收传递过来的参数
    const {
      index
    } = e.detail;
    let {
      tabs
    } = this.data;
    tabs.forEach((v, i) => i === index ? v.isActive = true : v.isActive = false);
    this.setData({
      tabs
    })
  }
})

实现效果如下:
在这里插入图片描述

7. ⽣命周期

分为应⽤⽣命周期⻚⾯⽣命周期

关于小程序前后台的定义和小程序的运行机制,请参考运行机制章节。

7.1.应⽤⽣命周期

应⽤⽣命周期

在这里插入图片描述

//app.js
App({
  //  1 应用第一次启动的就会触发的事件  
  onLaunch() {
    //  在应用第一次启动的时候 获取用户的个人信息 
    // console.log("onLaunch");
    // aabbcc

    // 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: '/pages/demo09/demo09' 
    });  
      
    // console.log("onPageNotFound");
  }
})

7.2.⻚⾯⽣命周期

⻚⾯⽣命周期

在这里插入图片描述

// pages/demo18/demo18.js
Page({

  /**
   * 页面的初始数据
   */
  data: {

  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    console.log("onLoad");
    // onLoad发送异步请求来初始化页面数据 
  },
  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {
    console.log("onShow");
  },
  /**
    * 生命周期函数--监听页面初次渲染完成
    */
  onReady: function () {
    console.log("onReady");
  },
  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {
    console.log("onHide");
  },

  /**
   * 生命周期函数--监听页面卸载 也是可以通过点击超链接来演示 
   * 
   */
  onUnload: function () {
    console.log("onUnload");
  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {
    console.log("onPullDownRefresh");
    // 页面的数据 或者效果 重新 刷新
  },

  /**
   * 页面上拉触底事件的处理函数
   * 需要让页面 出现上下滚动才行 
   */
  onReachBottom: function () {
    console.log("onReachBottom");
    // 上拉加载下一页数据 
  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {
    console.log("onShareAppMessage");
  },
  /**
   * 页面滚动 就可以触发 
   */
  onPageScroll(){
    console.log("onPageScroll");
  },
  /**
   * 页面的尺寸发生改变的时候 触发
   * 小程序 发生了 横屏竖屏 切换的时候触发 
   */
  onResize(){
    console.log("onResize");
  },
  /**
   * 1 必须要求当前页面 也是tabbar页面
   * 2 点击的自己的tab item的时候才触发
   */
  onTabItemTap(){
    console.log("onTabItemTap");
  }
})
<!--pages/demo18/demo18.wxml-->
<text>pages/demo18/demo18.wxml</text>

<navigator url="/pages/demo17/demo17" open-type="navigate">
  demo17
</navigator>
  
<navigator url="/pages/demo17/demo17" open-type="redirect">
  demo17 redirect
</navigator>
<view>1</view>
<view>2</view>
<view>3</view>
<view>4</view>
<view>5</view>
<view>6</view>
<view>7</view>
<view>8</view>
<view>9</view>
<view>10</view>
<view>11</view>
<view>12</view>
<view>13</view>
<view>14</view>
<view>15</view>
<view>16</view>
<view>17</view>
<view>18</view>
<view>19</view>
<view>20</view>
<view>21</view>
<view>22</view>
<view>23</view>
<view>24</view>
<view>25</view>
<view>26</view>
<view>27</view>
<view>28</view>
<view>29</view>
<view>30</view>
<view>31</view>
<view>32</view>
<view>33</view>
<view>34</view>
<view>35</view>
<view>36</view>
<view>37</view>
<view>38</view>
<view>39</view>
<view>40</view>
<view>41</view>
<view>42</view>
<view>43</view>
<view>44</view>
<view>45</view>
<view>46</view>
<view>47</view>
<view>48</view>
<view>49</view>
<view>50</view>
<view>51</view>
<view>52</view>
<view>53</view>
<view>54</view>
<view>55</view>
<view>56</view>
<view>57</view>
<view>58</view>
<view>59</view>
<view>60</view>
<view>61</view>
<view>62</view>
<view>63</view>
<view>64</view>
<view>65</view>
<view>66</view>
<view>67</view>
<view>68</view>
<view>69</view>
<view>70</view>
<view>71</view>
<view>72</view>
<view>73</view>
<view>74</view>
<view>75</view>
<view>76</view>
<view>77</view>
<view>78</view>
<view>79</view>
<view>80</view>
<view>81</view>
<view>82</view>
<view>83</view>
<view>84</view>
<view>85</view>
<view>86</view>
<view>87</view>
<view>88</view>
<view>89</view>
<view>90</view>
<view>91</view>
<view>92</view>
<view>93</view>
<view>94</view>
<view>95</view>
<view>96</view>
<view>97</view>
<view>98</view>
<view>99</view>
<view>100</view>
  

7.3.⻚⾯⽣命周期图解

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值