原生小程序 - 内置组件

108 阅读5分钟

Text

Text组件用于显示文本, 类似于span标签, 是行内元素

<text>text的基本使用</text>

<!--
  默认情况下,用户是不可以选中文本的
  可以设置user-select以开启
  开启后 长按可以选中文本
-->
<text user-select>Hello World</text>

<!-- 关闭空格折叠 并设置连续空格显示方式 -->
<text space="nbsp">Hello  World</text>

<!-- text默认并不会解析字符实体 -->
<text>&gt;</text>

<!-- 可以设置decode来解析字符实体 -->
<text decode>&gt;</text>
<view>
  <!--
		text中元素如果换行
		之前的换行会被识别,文本后的换行会被忽略
	-->
  <text> 
    ss
  </text>
</view>

image.png

Button

Button组件用于创建按钮,默认块级元素

<button>按钮默认是块级元素</button>

<button size="mini">可以设置size属性将按钮转换为行内级元素</button>

<button type="primary">可以通过type属性为button设置默认样式</button>

<!-- 所谓镂空效果 即为背景色透明 且加上对应的边框 -->
<button plain>可以通过plain属性设置按钮镂空效果</button>

<button disabled>可以设置disabled属性禁止按钮交互</button>

<button loading>可以设置loading属性 使按钮处于loading状态</button>

<button hover-class="active">当按钮被按下后,按钮就会自动添加hover-class属性对应的值作为按钮的样式</button>

open-type

open-type用户获取一些特殊性的权限 即微信开放能力,可以绑定一些特殊的事件

获取用户信息

<!-- 
  早期获取用户信息需要通过open-type="getUserInfo" 和 bindgetUserInfo回调来获取
  但是最新的小程序SDK中对于获取用户信息已经发生了改变
  新的小程序SDK中获取用户个人信息需要通过getUserProfile

  注意: 事件绑定的时候 不需要使用mustache语法
-->
<button bindtap="getUserInfo">获取用户信息</button>
Page({
  async getUserInfo() {
    // 早期的小程序API不支持使用Promise风格进行调用
    // 而最新的小程序API即执行使用Promise风格进行调用 也执行使用回调函数的形式进行调用
  
    // 以回调函数形式获取用户信息
    wx.getUserProfile({
      // desc 是描述信息 必填项
      // 一般为 获取用户信息后 用来进行什么操作
      desc: '获取用户信息',
      success: res => console.log(res.userInfo)
    })

    // 以promise形式获取用户信息
    const res = await wx.getUserProfile({
      desc: '获取用户信息'
    })
    
    console.log(res.userInfo)
  }
})

获取用户手机号

<!-- 
  获取用户手机号 依旧是需要使用之前设置open-type的方式来进行调用  
  当open-type的值为getPhoneNumber时候, 点击按钮就会触发bindgetphonenumber回调

  ps: 个人开发者是无法获取用户手机号 
      企业开发者会返回token,需要通过自己服务器将token和appSecret传递给微信服务器以换取对应的手机号
-->
<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">获取手机号</button>
Page({
  getPhoneNumber(e) {
    // 个人开发者无法获取手机号,所以会返回错误提示,提示没有权限
    console.log(e.detail)
  }
})

View

视图组件(块级元素,独占一行,通常用作容器组件)

<!-- 
	view上也可以绑定其它事件,也可以设置hover-class
  也可以通过设置hover-stop-propagation属性来阻止事件冒泡
-->
<view>基本使用</view>

Image

<!-- 当一个组件没有内容的时候 可以写成单标签 但必须要严格闭合 -->
<!-- image使用src来指定图片路径 图片路径可以是本地图片 也可以是网络图片 -->
<!-- 默认路径 如果以 / 开头 那么那个/表示的是项目根目录 -->
<!-- image组件是行内替换元素 有默认的宽高 默认的宽高为 320 * 240 -->
<image src="/assets/tabbar/cart.png" />

mode属性

<!-- 我们可以通过mode属性 来指定图片对应的缩放模式 -->
<image src="/assets/tabbar/cart.png" mode="widthFix" />
合法值说明
scaleToFill默认值 - 压缩图片 不保证图片的宽高比,不会裁剪图片 使图片的宽高完全拉伸至填满 image 元素
aspectFill裁剪模式 保持纵横比缩放图片,只保证图片的短边能完全显示出来
也就是说,图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取
类似于background-size中的cover属性
aspectFit缩放模式,保持纵横比缩放图片,使图片的长边能完全显示出来
也就是说,可以完整地将图片显示出来
类似于background-size的contain属性
widthFix缩放模式,宽度不变,高度自动变化,保持原图宽高比不变
即按照宽度 自适应高度
是使用最多的属性值
heightFix缩放模式,高度不变,宽度自动变化,保持原图宽高比不变
即按照高度 自适应宽度
top裁剪模式,不缩放图片,只显示图片的顶部区域
bottom裁剪模式,不缩放图片,只显示图片的底部区域
left裁剪模式,不缩放图片,只显示图片的左边区域
right裁剪模式,不缩放图片,只显示图片的右边区域
center裁剪模式,不缩放图片,只显示图片的中间区域
top left裁剪模式,不缩放图片,只显示图片的左上边区域
top right裁剪模式,不缩放图片,只显示图片的右上边区域
bottom left裁剪模式,不缩放图片,只显示图片的左下边区域
bottom right裁剪模式,不缩放图片,只显示图片的右下边区域

chooseMedia

chooseMedia() {
  wx.chooseMedia({
    mediaType: 'image',
  }).then(res => console.log(res))
}

scroll-view

scroll-view是一个可以进行内容滚动的view

默认情况下,scroll-view的行为和view是一致的

如果要开启scroll-view的滚动行为,需要满足如下两点:

  1. scroll-view的高度或宽度必须小于其内部的高度和宽度
  2. scroll-view必须设置scroll-xscroll-y属性开启对应的滚动

ps:

对于scroll-view,如果内容溢出(可以滑动)的情况下

设置scroll-view的margin-right和margin-bottom是无效的

推荐使用padding结合border-box

上下滚动

<!-- scroll-view 的 height 被设置为了50px -->
<scroll-view scroll-y class="scroll">
  <block wx:for="{{5}}" wx:key="*this">
    <view style="background-color: skyblue;">{{item}}</view>
  </block>
</scroll-view>

水平滚动

<!-- 
  默认情况下 对scroll-view设置flex布局是没有任何效果的
  需要使用enable-flex属性开启 flex布局
-->
<scroll-view scroll-x class="scroll" enable-flex>
  <block wx:for="{{5}}" wx:key="*this">
    <view class="item" style="background-color: skyblue;">{{item}}</view>
  </block>
</scroll-view>

示例

<!-- 
  bindscrolltolower -  滚动到底部 或 右边的时候 触发的回调
  bindscrolltoupper - 滚动到顶部 或 左边的时候 触发的回调
  bindscroll - 滚动时候触发的回调
-->
<scroll-view 
  scroll-x 
  class="scroll" 
  enable-flex 
  bindscrolltolower="scrolltolower"
  bindscrolltoupper="scrolltoupper"
  bindscroll="handleScroll"
>
  <block wx:for="{{5}}" wx:key="*this">
    <view class="item" style="background-color: skyblue;">{{item}}</view>
  </block>
</scroll-view>
Page({
  scrolltolower() {
    console.log('scrolltolower');
  },

  scrolltoupper() {
    console.log('scrolltoupper');
  },

  handleScroll(e) {
    // scrollLeft 或 scrollTop 记录着 卷曲出去的距离
    // scrollWidth 记录着 scrollView 一共可以滚动的距离
    // deltaX和deltaY 当值为负数 表示 向右滚动  值为正数 表示 向左滚动
    console.log(e.detail);
  }
})

input

<!-- 在小程序中 所有的单标签组件 都必须严格闭合 -->
<!-- 默认情况下 input组件是没有任何的样式的,需要手动进行添加 -->
<!-- 在input组件上 可以使用 model:value 来进行小程序的双向数据绑定 -->
<input type="text" model:value="{{ msg }}" />

swiper

<!-- 
  swiper 和 swiper-item是微信内置的轮播图组件
	默认情况下 swiper有固定的150px的高度,其高度并不是由内容填充出来的
-->
<swiper autoplay circular>

  <block wx:for="{{ banners }}" wx:key="acm">
    <swiper-item>

      <image mode="widthFix" src="{{ item.image }}"></image>
    </swiper-item>
  </block>
</swiper>

因为swiper默认有150px的高度,而图片的mode 一般设置为widthFix

所以可能会出现因为图片高度不够,而导致的不足以填满整个swiper的情况发生

image.png

image.png

所以,最为简单的解决方式就是在图片加载完毕后,去获取图片的高度,并将图片的高度设置给swiper组件, 从而覆盖swiper组件的默认高度

<!-- swiper的高度 根据 image的高度 进行设置 -->
<swiper 
  autoplay 
  circular 
  indicator-dots 
  class="swiper"
  style="height: {{ swiperHeight }}px"
>
  <swiper-item 
     wx:for="{{ banners }}" 
     wx:key="targetId" 
     class="swiper-item"
  >
    <image 
      src="{{ item.imageUrl }}" 
      class="swiper-image" 
      mode="widthFix" 
      bind:load="handleImageLoad"  
    />
  </swiper-item>
</swiper>
import { querySelector } from '../../utils/index'

Page({
  data: {
    // 默认值设置为150 是因为swiper组件的默认高度是150px
    swiperHeight: 150,
    isInitSwiper: false,
  },

  async handleImageLoad() {
    // 1. 轮播图片存在多张图片
    // 2. 每次图片加载完成后 都会触发对应的load事件
    // 所以handleImageLoad事件会被多次触发
    // 但是获取和设置swiper的高度只要设置一次就可以了
    // 所以这里使用isInitSwiper这个boolean类型的值来判断是否初始化过swiper的高度
    // ps: 这里使用节流函数来控制handleImageLoad的执行次数也是可以的
    if (this.data.isInitSwiper) return

    this.data.isInitSwiper = true

    const { height } = await querySelector('.swiper-image')
    this.setData({
      swiperHeight: height
    })
  }
})
// @filename /src/utils/querySelector
export function querySelector(selector) {
  return new Promise((resolve, reject) => {
    try {
      // 通过wx.createSelectorQuery创建一个查询对象
      // https://developers.weixin.qq.com/miniprogram/dev/api/wxml/wx.createSelectorQuery.html
      const query = wx.createSelectorQuery()

      // 执行查询器对应需要查询的功能
      query.select(selector).boundingClientRect()

      // 执行对应的指令
      query.exec(res => resolve(res[0]))
    } catch (e) {
      reject(e)
    }
  })
}

组件共同属性

image.png