小部件(Widget)组件视图容器汇总(属性说明+代码明细)

发布时间:2024年01月15日

小部件(Widget)不同于小程序页面,仅支持有限的组件,用于绘制小部件(Widget) 的 UI 界面。现总结视图容器的内置组件明细:

view

属性说明

属性类型默认值必填说明备注
hover-classstringnone指定按下去的样式类。当?hover-class="none"?时,没有点击态效果
hover-start-timenumber50按住后多久出现点击态,单位毫秒
hover-stay-timenumber400手指松开后点击态保留时间,单位毫秒

示例代码

TYML
<view class="page-head">
	<view class="page-head-title">view</view>
	<view class="page-head-line"></view>
</view>
 
<view class="page-section">
  <view class="page-section-title l-r-padding">
    <view>flex-direction: row</view>
    <view>横向布局</view>
  </view>
  <view class="flex-wrp" style="flex-direction:row;justify-content: center;">
    <view class="flex-item demo-text-1">A</view>
    <view class="flex-item demo-text-2">B</view>
    <view class="flex-item demo-text-3">C</view>
  </view>
</view>
 
<view class="page-section">
  <view class="page-section-title l-r-padding">
    <view>flex-direction: column</view>
    <view>纵向布局</view>
  </view>
  <view class="flex-wrp" style="flex-direction:column;">
    <view class="flex-item flex-item-V demo-text-1">A</view>
    <view class="flex-item flex-item-V demo-text-2">B</view>
    <view class="flex-item flex-item-V demo-text-3">C</view>
  </view>
</view>

?

scroll-view

可滚动视图区域,可实现横向滚动和竖向滚动。使用竖向滚动时,需要给定一个固定高度,可以通过样式来设置 height。组件属性的长度单位支持 px 和 rpx。

属性说明

属性类型默认值必填说明备注
scroll-xbooleanfalse允许横向滚动
scroll-ybooleanfalse允许纵向滚动
upper-thresholdnumber/string50距顶部/左边多远时,触发 scrolltoupper 事件
lower-thresholdnumber/string50距底部/右边多远时,触发 scrolltolower 事件
scroll-topnumber/string设置竖向滚动条位置
scroll-leftnumber/string设置横向滚动条位置
scroll-into-viewstring值应为某子元素 id(id 不能以数字开头)。设置哪个方向可滚动,则在哪个方向滚动到该元素
scroll-with-animationbooleanfalse在设置滚动条位置时使用动画过渡
refresher-enabledbooleanfalse开启自定义下拉刷新
refresher-thresholdnumber45设置自定义下拉刷新阈值
refresher-default-stylestring"black"设置自定义下拉刷新默认样式,支持设置 black、white、none, none 表示不使用默认样式
refresher-backgroundstring"#FFF"设置自定义下拉刷新区域背景颜色
refresher-triggeredbooleanfalse设置当前下拉刷新状态,true 表示下拉刷新已经被触发,false 表示下拉刷新未被触发
bind:scrolleventhandle--滚动时触
bind:scrolltouppereventhandle--滚动到顶部/左边时触发
bind:scrolltolowereventhandle--滚动到底部/右边时触发
bind:refresherpullingeventhandle--自定义下拉刷新控件被下拉
bind:refresherrefresheventhandle--自定义下拉刷新被触发
bind:refresherrestoreeventhandle--自定义下拉刷新被复位
bind:refresheraborteventhandle--自定义下拉刷新被中止

示例代码

TYML
<view class="page-head">
	<view class="page-head-title">scroll-view</view>
	<view class="page-head-line"></view>
</view>
 
<view class="page-section">
  <view class="page-section-title l-r-padding">
    <text>Vertical Scroll</text>
    <view>纵向滚动</view>
  </view>
  <view class="page-section-spacing">
    <scroll-view
      style="height: 150px;"
      scrollY="{{true}}"
      bind:scroll="scroll"
      bind:scrolltoupper="upper"
      bind:scrolltolower="lower"
      >
      <view id="demo1" class="scroll-view-item demo-text-1">A</view>
      <view id="demo2"  class="scroll-view-item demo-text-2">B</view>
      <view id="demo3" class="scroll-view-item demo-text-3">C</view>
    </scroll-view>
  </view>
</view>
 
<view class="page-section">
  <view class="page-section-title l-r-padding">
    <text>Horizontal Scroll</text>
    <view>横向滚</view>
  </view>
  <view class="page-section-spacing">
    <scroll-view
      class="scroll-view_H"
      scrollX="{{true}}"
      scrollIntoView="{{toView}}"
      scrollWithAnimation="{{true}}"
      bind:scroll="scroll"
      bind:scrolltoupper="upper"
      bind:scrolltolower="lower"
      >
      <view class="box">
        <view id="demo4" class="scroll-view-item_H demo-text-1">A</view>
        <view id="demo5"  class="scroll-view-item_H demo-text-2">B</view>
        <view id="demo6" class="scroll-view-item_H demo-text-3">C</view>
      </view>
    </scroll-view>
  </view>
</view>

JS
Page({
  data: {
    toView: 'demo5',
  },
  upper(e) {
    console.log('demo upper', e);
  },
  lower(e) {
    console.log('demo lower', e);
  },
  scroll(e) {
    console.log('demo scroll', e);
  },
});

TYSS
.page-section {
  width: 100%;
  display: block;
  margin: 30px 0;
}
.page-section:last-child {
  margin-bottom: 0;
}
.page-section-spacing {
  margin-top: 30px;
  box-sizing: border-box;
  padding: 0 40px;
}
.scroll-view_H {
  width: 100%;
  white-space: nowrap;
}
.box {
  display: flex;
  flex-wrap: nowrap;
  width: 300%;
}
.scroll-view-item_H {
  flex: 1;
  height: 150px;
  color: #ffffff;
  font-size: 13px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.scroll-view-item {
  height: 150px;
  color: #ffffff;
  font-size: 13px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.demo-text-1 {
  background-color: #1aad19;
}
.demo-text-2 {
  background-color: #2782d7;
}
.demo-text-3 {
  background-color: #f1f1f1;
  color: #353535;
}

常见问题(FAQ)

为何 scroll-view 在 popup 扩展组件中无法滑动?

popup 组件上加上 disableScroll={{false}} 属性才能滑动。

如何监听 scroll-view 滚动到底部?

可以直接在?onScroll?方法中进行处理,使用?onScrollToLower?监听?scroll-view?的滚动高度来进行判断是否滑动到了底部。?scrollHeight?是?scroll-view?里面所有?view?的高度和,scrollTop?是滚动的值。

自定义页面蒙层的时候,当滚动蒙层里面的内容,蒙层底下页面也能跟着滑动?

可以给蒙层内部?scroll-view?或?view?添加?catch:touchmove事件,阻止事件冒泡。

swiper

滑块视图容器。其中只可放置 swiper-item 组件,否则会导致未定义的行为。

属性说明

属性类型默认值必填说明
indicator-dotsbooleanfalse是否显示面板指示点
indicator-colorcolor#666666指示点颜色
indicator-active-colorcolor#333333当前选中的指示点颜色
autoplaybooleanfalse是否自动切换
currentnumber0当前所在滑块的 index
intervalnumber5000自动切换时间间隔,单位 ms
durationnumber500滑动动画时长,单位 ms
circularbooleanfalse是否采用衔接滑动
verticalbooleanfalse滑动方向是否为纵向
bind:changeeventhandlecurrent 改变时会触发 change 事件,event.detail = {current, source}
bind:animationfinisheventhandle动画结束时会触发 animationfinish 事件,event.detail 同上

change 事件 source 返回值

change 事件的 source 字段,表示导致变更的原因,可能值如下:

说明
autoplay自动播放导致 swiper 变化
touch用户划动引起 swiper 变化
空字符串其它原因

示例代码

TYML
<view class="container">
  <view class="page-body">
    <view class="page-section page-section-spacing swiper">
      <swiper
        indicator-dots="{{indicatorDots}}"
        autoplay="{{autoplay}}"
        circular="{{circular}}"
        vertical="{{vertical}}"
        interval="{{interval}}"
        duration="{{duration}}"
        >
        <block ty:for="{{background}}" ty:key="*this">
          <swiper-item>
            <view class="swiper-item {{item}}"></view>
          </swiper-item>
        </block>
      </swiper>
    </view>
    <view class="page-section" style="margin-top: 40rpx;margin-bottom: 0;">
      <view class="tyui-cells tyui-cells_after-title">
        <view class="page-cell tyui-cell_switch">
          <view class="tyui-cell__bd">指示点</view>
          <view class="tyui-cell__ft">
            <switch checked="{{indicatorDots}}" bind:change="changeProperty" data-property-name="indicatorDots" />
          </view>
        </view>
        <view class="page-cell tyui-cell_switch">
          <view class="tyui-cell__bd">自动播放</view>
          <view class="tyui-cell__ft">
            <switch checked="{{autoplay}}" bind:change="changeProperty" data-property-name="autoplay" />
          </view>
        </view>
        <view class="page-cell tyui-cell_switch">
          <view class="tyui-cell__bd">衔接滑动</view>
          <view class="tyui-cell__ft">
            <switch checked="{{circular}}" bind:change="changeProperty" data-property-name="circular" />
          </view>
        </view>
        <view class="page-cell tyui-cell_switch">
          <view class="tyui-cell__bd">竖向</view>
          <view class="tyui-cell__ft">
            <switch checked="{{vertical}}" bind:change="changeProperty" data-property-name="vertical" />
          </view>
        </view>
      </view>
    </view>
 
    <view class="page-section page-section-spacing">
      <view class="page-section-title">
        <text>幻灯片切换时长(ms)</text>
        <text class="info">{{duration}}</text>
      </view>
      <slider value="{{duration}}" min="{{500}}" max="{{2000}}" bind:change="changeProperty" data-property-name="duration" />
      <view class="page-section-title">
        <text>自动播放间隔时长(ms)</text>
        <text class="info">{{interval}}</text>
      </view>
      <slider value="{{interval}}" min="{{2000}}" max="{{10000}}" bind:change="changeProperty" data-property-name="interval" />
    </view>
  </view>
</view>

JS
Page({
  data: {
    background: ['demo-text-1', 'demo-text-2', 'demo-text-3'],
    indicatorDots: true,
    vertical: false,
    autoplay: false,
    circular: true,
    interval: 2000,
    duration: 500,
    previousMargin: 0,
    nextMargin: 0,
  },
  change: function (e) {},
  changeProperty: function (e) {
    var propertyName = e.currentTarget.dataset.propertyName;
    var newData = {};
    newData[propertyName] = e.detail.value;
    this.setData(newData);
  },
  changeIndicatorDots: function (e) {
    this.setData({
      indicatorDots: !this.data.indicatorDots,
    });
  },
  changeAutoplay: function (e) {
    this.setData({
      autoplay: !this.data.autoplay,
    });
  },
  intervalChange: function (e) {
    this.setData({
      interval: e.detail.value,
    });
  },
  durationChange: function (e) {
    this.setData({
      duration: e.detail.value,
    });
  },
});

?

movable-area

movable-view 的可移动区域。

属性说明

属性类型默认值必填说明
scale-areabooleanfalse当里面的 movable-view 设置为支持双指缩放时,设置此值可将缩放手势生效区域修改为整个 movable-area

示例代码

TYML
<view class="page-section">
  <view class="page-section-title l-r-padding">movable移动功能</view>
  <view class="area-wrap">
    <movable-area class="area">
      <movable-view class="block" x="{{x}}" y="{{y}}" direction="all">
        text
      </movable-view>
    </movable-area>
  </view>
  <view class="btn-wrap">
    <view class="btn-line">
      <button type="primary" bind:tap="moveFn" class="btn">点击移动到(30px, 30px)</button>
    </view>
    <view class="btn-line">
      <button type="primary" bind:tap="moveStep" class="btn sec-btn">点击移动到({{x + 10}}px, {{y + 10}}px)</button>
    </view>
  </view>
</view>
 
<view class="page-section">
  <view class="page-section-title l-r-padding">只可以横向移动</view>
  <view class="area-wrap">
    <movable-area class="area">
      <movable-view class="block" direction="horizontal">text</movable-view>
    </movable-area>
  </view>
</view>
 
<view class="page-section">
  <view class="page-section-title l-r-padding">只可以纵向移动</view>
  <view class="area-wrap">
    <movable-area class="area">
      <movable-view class="block" direction="vertical">text</movable-view>
    </movable-area>
  </view>
</view>
 
<view class="page-section">
  <view class="page-section-title l-r-padding">可超出边界</view>
  <view class="area-wrap">
    <movable-area class="area">
      <movable-view class="block" direction="all" out-of-bounds="true">text</movable-view>
    </movable-area>
  </view>
</view>

JS
Page({
  data: {
    x: 0,
    y: 0,
  },
  // 移动到30px,30px
  moveFn() {
    this.setData({
      x: 30,
      y: 30,
    });
  },
  moveStep() {
    const x = this.data.x + 10;
    const y = this.data.y + 10;
    this.setData({
      x,
      y,
    });
  },
});

TYSS
.page-section {
  width: 100%;
  margin-bottom: 30px;
}
 
.area-wrap {
  display: flex;
  justify-content: space-around;
}
 
.area {
  flex: none;
  height: 200px;
  width: 200px;
  margin: 10px;
  background-color: #ccc;
  overflow: hidden;
}
 
.block {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 50px;
  width: 50px;
  background: var(--ty-native-primary-color);
  color: #fff;
}
 
.btn-line {
  text-align: center;
}
 
.btn-line .btn {
  display: inline-block;
  width: 240px;
}
 
.btn-line .sec-btn {
  margin-top: 10px;
}

?

movable-view

可移动的视图容器,在页面中可以拖拽滑动。movable-view 必须在 movable-area 组件中,并且必须是直接子节点,否则不能移动。?

属性说明

属性类型默认值必填说明
directionstringnonemovable-view 的移动方向,属性值有 all、vertical、horizontal、none
inertiabooleanfalsemovable-view 是否带有惯性
out-of-boundsbooleanfalse超过可移动区域后,movable-view 是否还可以移动
xnumber0定义 x 轴方向的偏移,如果 x 的值不在可移动范围内,会自动移动到可移动范围。改变 x 的值会触发动画
ynumber0定义 y 轴方向的偏移,如果 y 的值不在可移动范围内,会自动移动到可移动范围。改变 y 的值会触发动画
dampingnumber20阻尼系数,用于控制 x 或 y 改变时的动画和过界回弹的动画,值越大移动越快
frictionnumber2摩擦系数,用于控制惯性滑动的动画,值越大摩擦力越大,滑动越快停止;必须大于 0,否则会被设置成默认值
disabledbooleanfalse是否禁用
scalebooleanfalse是否支持双指缩放,默认缩放手势生效区域是在 movable-view 内
scale-minnumber0.5定义缩放倍数最小值
scale-maxnumber10定义缩放倍数最大值
scale-valuenumber1定义缩放倍数,取值范围为 0.5 - 10
animationbooleantrue是否使用动画
bind:changeeventhandle拖动过程中触发的事件,event.detail = {x, y, source}
bind:scaleeventhandle缩放过程中触发的事件,event.detail = {x, y, scale}

bind:change?返回的?source?表示产生移动的原因

说明
touch拖动
touch-out-of-bounds超出移动范围
out-of-bounds超出移动范围后的回弹
friction惯性
空字符串setData

注意事项

tip:?movable-view?必须设置?width?和?height?属性,不设置默认为?10px?tip:?movable-view?默认为绝对定位,top?和?left?属性为?0px。

?

page-container

?页面容器。用于实现类似 popup 弹出层的效果,可以通过控制 show 属性来实现显示/隐藏。

功能描述

页面容器。

小程序如果在页面内进行复杂的界面设计(如在页面内弹出半屏的弹窗、在页面内加载一个全屏的子页面等),用户进行返回操作会直接离开当前页面,不符合用户预期,预期应为关闭当前弹出的组件。 为此提供“假页”容器组件,效果类似于 popup 弹出层。

页面内存 page-container 时,当用户进行返回操作,关闭该容器不关闭页面。返回操作包括三种情形,右滑手势、安卓物理返回键和调用 navigateBack 接口。

容器版本 2.3.0+ 以上支持

注意:当页面状态触发 page-container 显示隐藏时,开发者需在 page-container 离开视图的相关事件中,将控制 page-container 的状态设置为 false,否则可能会影响再次打开 page-container。

属性说明

属性类型默认值必填说明
showbooleanfalse是否显示容器组件
durationnumber300动画时长,单位毫秒
z-indexnumber100z-index 层级
overlaybooleantrue是否显示遮罩层
positionstringbottom弹出位置,可选值为 top bottom right center
roundbooleanfalse是否显示圆角
overlay-stylestring自定义遮罩层样式
custom-stylestring自定义弹出层样式
bind:beforeentereventhandle进入前触发
bind:entereventhandle进入中触发
bind:afterentereventhandle进入后触发
bind:beforeleaveeventhandle离开前触发
bind:leaveeventhandle离开中触发
bind:afterleaveeventhandle离开后触发
bind:clickoverlayeventhandle点击遮罩层时触发

示例代码

TYML
<view class="title">弹出位置</view>
<view class="box">
  <button class="btn" bind:tap="popup" data-position="right">右侧弹出</button>
  <button class="btn" bind:tap="popup" data-position="top">顶部弹出</button>
  <button class="btn" bind:tap="popup" data-position="bottom">底部弹出</button>
  <button class="btn" bind:tap="popup" data-position="center">中央弹出</button>
</view>
 
<view class="title">弹窗圆角</view>
<view class="box">
  <button class="btn" bind:tap="changeRound">设置{{round ? '直角' : '圆角'}}</button>
</view>
 
<view class="title">遮罩层</view>
<view class="box">
  <button class="btn" bind:tap="changeOverlay">设置{{overlay ? '无' : '有'}}遮罩</button>
  <button class="btn" bind:tap="changeOverlayStyle" data-type="black">黑色半透明遮罩</button>
  <button class="btn" bind:tap="changeOverlayStyle" data-type="white">白色半透明遮罩</button>
  <button class="btn" bind:tap="changeOverlayStyle" data-type="blur">模糊遮罩</button>
</view>
 
<page-container
  style="height: 500px"
  show="{{show}}"
  round="{{round}}"
  overlay="{{overlay}}"
  duration="{{duration}}"
  position="{{position}}"
  close-on-slide-down="{{false}}"
  bind:beforeenter="onBeforeEnter"
  bind:enter="onEnter"
  bind:afterenter="onAfterEnter"
  bind:beforeleave="onBeforeLeave"
  bind:leave="onLeave"
  bind:afterleave="onAfterLeave"
  bind:clickoverlay="onClickOverlay"
  custom-style="{{customStyle}}"
  overlay-style="{{overlayStyle}}"
>
  <view class="detail-page">
    <button type="primary" bind:tap="exit">推出</button>
  </view>
</page-container>

JS
Page({
  data: {
    show: false,
    duration: 300,
    position: 'right',
    round: false,
    overlay: true,
    customStyle: '',
    overlayStyle: '',
  },
  onLoad: function () {},
  onShow() {},
 
  popup(e) {
    const position = e.currentTarget.dataset.position;
    let customStyle = '';
    let duration = this.data.duration;
    switch (position) {
      case 'top':
      case 'bottom':
        customStyle = '';
        break;
      case 'right':
        break;
    }
    this.setData({
      position,
      show: true,
      customStyle,
      duration,
    });
  },
 
  changeRound() {
    this.setData({ round: !this.data.round });
  },
 
  changeOverlay() {
    this.setData({ overlay: !this.data.overlay, show: true });
  },
 
  changeOverlayStyle(e) {
    let overlayStyle = '';
    const type = e.currentTarget.dataset.type;
    switch (type) {
      case 'black':
        overlayStyle = 'background-color: rgba(0, 0, 0, 0.7)';
        break;
      case 'white':
        overlayStyle = 'background-color: rgba(255, 255, 255, 0.7)';
        break;
      case 'blur':
        overlayStyle =
          'background-color: rgba(0, 0, 0, 0.7); filter: blur(4px);';
    }
    this.setData({ overlayStyle, show: true });
  },
 
  exit() {
    this.setData({ show: false });
  },
 
  onBeforeEnter(res) {
    console.log(res);
  },
  onEnter(res) {
    console.log(res);
  },
  onAfterEnter(res) {
    console.log(res);
  },
  onBeforeLeave(res) {
    console.log(res);
  },
  onLeave(res) {
    console.log(res);
    this.setData({ show: false });
  },
  onAfterLeave(res) {
    console.log(res);
  },
 
  onClickOverlay(res) {
    this.setData({
      show: false,
    });
  },
});

TYSS
.box {
  margin: 0 20px;
}
 
.title {
  margin: 0;
  padding: 32px 16px 16px;
  color: rgba(0, 0, 0, 0.5);
  font-weight: normal;
  font-size: 14px;
  line-height: 20px;
  text-align: center;
}
 
.btn {
  display: block;
  width: 100%;
  margin: 10px 0;
  background-color: #fff;
}
 
.detail-page {
  width: 100%;
  height: 100%;
  min-height: 300px;
  display: flex;
  align-items: center;
  justify-content: center;
}

?

cover-view

基础库 2.7.0 开始支持, 低版本需做兼容处理。

功能描述

覆盖在原生组件之上的文本视图。

Bug & Tip

  1. tip: 需在原生组件上覆盖其它组件, 且该组件不作为原生组件子节点时, 必须在最外层使用?cover-view?包裹住, 其它场景不建议使用cover-view
  2. tip: 不要嵌套使用?cover-view?,?cover-view?只作为覆盖在原生组件之上的包裹标签使用
  3. tip: 不要作为原生组件子节点使用
  4. tip: 建议cover-view?子节点不要溢出父节点

示例代码

TYML
<view class="container">
  <map style="width: 100%; height: 300px;" latitude="{{latitude}}" longitude="{{longitude}}"></map>
  <cover-view class="cover-view">
    <view class="flex-wrp" style="flex-direction:row;" bindtap="coverTap">
      <view class="flex-item demo-text-1"></view>
      <view class="flex-item demo-text-2"></view>
      <view class="flex-item demo-text-3"></view>
    </view>
  </cover-view>
</view>

JS
Page({
  data: {
    latitude: 23.099994,
    longitude: 113.32452,
  },
  coverTap(e) {
    console.log(e);
  },
});

CSS
.container {
  position: relative;
}
 
.cover-view {
  position: absolute;
  top: calc(50% - 150rpx);
  left: calc(50% - 300rpx);
}
 
.flex-wrp {
  display: flex;
}
 
.flex-item {
  width: 200rpx;
  height: 300rpx;
  font-size: 26rpx;
}
 
.demo-text-1 {
  background: rgba(26, 173, 25, 0.7);
}
 
.demo-text-2 {
  background: rgba(39, 130, 215, 0.7);
}
 
.demo-text-3 {
  background: rgba(255, 255, 255, 0.7);
}
文章来源:https://blog.csdn.net/Ms_Smart/article/details/135596251
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。