如何在快应用中实现滑动操作组件
1. 什么是滑动操作组件
在实际的移动应用程序交互方式中,最常见的就是滑动操作。像左右滑动切换页面,手指张开来放大图片等,都是由滑动操作来完成的。本文滑动操作组件是指通过手势滑动呼出隐藏的操作按钮。
如下图所示:
以上滑动操作组件具有如下特点:
- 左右滑动均支持,滑动可呼出、隐藏操作按钮栏;
- 操作按钮可配置多个;
- 操作按钮可设置背景色、字体、宽度等;
- 点击操作按钮,可隐藏操作栏;
- 呼出操作栏时,界面所有的UI元素都相应移动;
2 基本实现
2.1 滑动操作组件化设计
定义支持滑动操作的组件swipe_item,父组件引用,引用时传递操作按钮、操作按钮样式。滑动操作子组件需要实现手势滑动处理。
代码结构如下:
<import name="swipeitem" src="../Component/swipe_item.ux"></import>
<template>
<div class="container">
<swipeitem right-options="{{rightBtns}}" left-options="{{leftBtns}}" @swipebtnclick="swipeItemClick">
<text>左右都有混合滚动</text>
</swipeitem>
</div>
</template>
2.2子组件swipe_item属性设计
2.3支持的属性
属性 |
类型 |
是否必选 |
默认值 |
描述 |
identity |
Number |
否 |
组件唯一标识,当autoClose为true时,必须要设置 |
|
disabled |
Boolean |
否 |
false |
是否禁止滑动 |
autoClose |
Boolean |
是 |
true |
滑动打开当前组件,是否关闭其他组件 |
threshold |
Number |
否 |
30 |
滑动缺省距离 |
leftOptions |
Array[Option] |
否 |
左侧操作栏内容及样式 |
|
rightOptions |
Array[Option] |
否 |
右侧操作栏内容及样式 |
Option对象参数如下:
属性 |
类型 |
是否必选 |
描述 |
txt |
String |
否 |
按钮文字 |
style |
Object |
是 |
按钮样式 |
style对象参数如下:
属性 |
类型 |
是否必选 |
描述 |
backgroundColor |
Color |
否 |
按钮背景色 |
txtColor |
Color |
否 |
按钮颜色 |
fontsize |
Number |
否 |
文字大小 |
btnwidth |
Number |
是 |
按钮宽度 |
支持的事件
事件名称 |
事件传递参数 |
描述 |
swipebtnclick |
{clickIndex:1, position:left|right, btnValue:btnText} |
点击操作栏按钮时触发事件; clickIndex:左或右操作栏上点击的按钮数组索引; position:所点击的操作栏位置,参数值有left和right; btnValue:所点击的按钮文字; |
centerclick |
{} |
点击显示在屏幕中间内容时触发事件 |
swipestatechange |
{isOpened:true|false} |
操作栏打开或关闭时触发 |
2.4 swipe_item子组件布局
- 布局结构:由左侧操作栏+中间屏幕显示内容+右侧操作栏组成的横向div;
- 左侧操作栏、右侧操作栏都是基于leftOptions、rightOptions操作选项内容数组,采用用for循环形成横向布局渲染;
- 中间在屏幕内显示内容是动态变化的,每个产品要显示的内容和UI是不同的,所以采用了slot插槽,由使用swipe_item组件的页面来完成中间内容的布局。
- 中间布局宽度需设置整个屏幕的宽度,即750px;
2.5 swipe_item子组件css
- 宽度:虽然滑动操作组件在初始状态下左右操作栏都是隐藏的,但是实际属于整个布局的一部分,如果不能正确计算根节点的宽度,会导致滑动的时候,操作栏上无内容。
- 动画:初始状态下,需要满足左右操作栏都是隐藏的,只有中间内容是可见的。正常布局下(见图3),左操作栏是显示的,所以使用了transform动画样式,将根节点平移左操作栏宽度的距离,这样就确保初始状态下操作栏都是隐藏的。
- 按鈕背景色、文字大小、文字顔色: 如果父组件没有设置,子组件设置默认的值,见图4;
|
|
图3 正常布局效果 |
图4 操作栏按钮默认背景色效果 |
2.6 手势滑动
监听手势touchstart、touchmove、touchend事件,计算手指滑动像素,同时调用X轴的平移动画animate方法,实现组件的移动效果。
- touchstart:记录起始触摸点;
- touchmove:滑动距离ds>0 表示手指向右滑动,反之向左滑动,滑动过程中调用animate()移动组件,达到打开或者隐藏操作栏的效果;如果滑动距离小于阈值threshold,不触发移动效果;如果禁止滑动即disabled值为true时,也不能触发滑动效果;
- touchend:滑动结束时触发,调用animate()控制操作栏最终显示位置,需要计算准确,防止组件移动过远或者过近,从而UI效果异常。
2.8 父子组件通信
当点击子组件操作栏上的按钮时,需要父组件处理业务逻辑,通过$emit()向父组件发送通知。注意,不要在子组件中处理业务逻辑,否则代码无法维护。
1) 操作栏按钮点击事件通知
- 页面调用子组件时,监听swipebtnclick事件;
- 子组件调用$emit()向页面发送通知;
2)中间内容部分点击事件通知
- 页面调用子组件时,监听centerclick事件;
- 当操作栏处于打开状态时,点击中间部分效果是隐藏操作栏。只有操作栏处于隐藏状态时,点击中间部分时,子组件调用$emit()向页面发送通知,页面自行处理业务逻辑,比如打开新的页面。
3)操作栏打开、关闭事件通知
- 页面调用子组件时,监听swipestatechange事件;
- 当操作栏处于打开或者关闭状态时,子组件调用$emit()向页面发送通知。
相关代码如下:
2.9 autoClose实现
滑动打开当前组件时,是否关闭其他组件,当autoClose设置为true时,identity属性必须设置,且唯一标识当前子组件。
- 当子组件1操作栏打开时,通过$emit()向页面发送状态事件swipestatechange;
- 父组件监听swipestatechange事件,通过$broadcast()方法向子组件发送关闭通知事件closeSwipeItem,通知其他子组件2,3,4等要关闭已经打开的操作栏;
- 子组件1,2,3,4等监听关闭closeSwipeItem事件,在事件句柄中处理关闭逻辑,注意操作栏打开的子组件1也会收到关闭事件,此处我们需要判断identity值,确保最新打开的子组件1不会出现打开又关闭的现象。
3总结
- 学习和熟悉快应用子组件的设计和属性定义;
- 学习和熟悉快应用手势事件;
- 学习和熟悉快应用动画;
- 注意滑动操作子组件swipe_item在list-item中不生效。
4代码附录
滑动操作子组件swipe_item.ux
<template>
<!-- Only one root node is allowed in template. -->
<div class="container" style="{{containerStyle}}" >
<div id="swipe_item" class="swipe" ontouchstart="dealTouchStart" ontouchmove="dealTouchMove" ontouchend="dealTouchEnd" >
<div class="left" id="leftbtns">
<block for="(index,item) in leftOptions">
<input type="button" class="btn"
style="background-color: {{calBtnBgColor(item.style.backgroundColor)}};
color:{{calBtnTxtColor(item.style.txtColor)}};
font-size:{{calBtnFontSize(item.style.fontsize)}}px;width:{{item.style.btnwidth}}px;"
value="{{item.txt}}" onclick="btnsClick(index,'left',item.txt)">
</input>
</block>
</div>
<div class="center" style="width:{{deviceLogicWidth}}px" onclick="dealClickCenter">
<slot ></slot>
</div>
<div class="right" id="rightbtns">
<block for="(index,item) in rightOptions">
<input type="button" class="btn"
style="background-color: {{calBtnBgColor(item.style.backgroundColor)}};
color:{{calBtnTxtColor(item.style.txtColor)}};
font-size:{{calBtnFontSize(item.style.fontsize)}}px;width:{{item.style.btnwidth}}px;"
value="{{item.txt}}" onclick="btnsClick(index,'right',item.txt)">
</input>
</block>
</div>
</div>
</div>
</template>
<style>
.container {
flex-direction: column;
justify-content: center;
}
.swipe {
flex-direction: row;
align-items: center;
}
.txt {
font-size: 40px;
width: 100%;
height: 100%;
}
.btn {
height: 100%;
}
.left {
flex-direction: row;
flex-shrink: 0;
height: 100%;
background-color: #a9a9a9;
}
.center {
flex-direction: row;
align-items: center;
padding: 16px;
flex-shrink: 0;
}
.right {
flex-direction: row;
flex-shrink: 0;
height: 100%;
background-color: #a9a9a9;
}
</style>
<script>
import device from '@system.device';
const defaultBtnBg="#f01f1f";
const defaultBtnFontSize=32;
const defaultBtnTxtColor="#dcdcdc";
module.exports = {
props: {
// 禁用
disabled: {
type: Boolean,
default: false
},
identity:{
type: String,
default: '0',
},
// 是否自动关闭
autoClose: {
type: Boolean,
default: true
},
// 滑动缺省距离
threshold: {
type: Number,
default: 30
},
// 左侧按钮内容
leftOptions: {
type: Array,
default() {
return []
}
},
// 右侧按钮内容
rightOptions: {
type: Array,
default() {
return []
}
}
},
data: {
movestartX: 0,
lastMoveX:0,
translateEndX: 0,
leftbtnsWidth: 0,
rightbtnsWidth: 0,
deviceLogicWidth:750,
isLeftOpened: false,
isRightOpened: false
},
computed: {
containerStyle() {
console.info("computed containerStyle begin")
var style = '';
let totalwidth=0;
let leftwidth=0;
this.leftOptions.forEach((item, index, array) => {
console.info("computed item="+JSON.stringify(item));
leftwidth+=item.style.btnwidth;
})
this.rightOptions.forEach((item, index, array) => {
totalwidth+=item.style.btnwidth;
})
totalwidth=totalwidth+this.deviceLogicWidth+leftwidth;
console.info("computed totawidth="+totalwidth+", left width="+leftwidth);
style += 'width:' + totalwidth + 'px;'
style += 'transform: translateX(-' + leftwidth + 'px);'
return style;
}
},
calBtnBgColor(color){
if(color!==undefined){
return color;
}
return defaultBtnBg;
},
calBtnFontSize(size){
if(size!==undefined){
return size;
}
return defaultBtnFontSize;
},
calBtnTxtColor(color){
if(color!==undefined){
return color;
}
return defaultBtnTxtColor;
},
onInit() {
console.info("oninit()");
this.$on('closeSwipeItem', this.closeFromParent);
setTimeout(() => {
this.calWidth();
}, 500);
},
calWidth() {
this.calLeftBtnsWidth();
this.calRightBtnsWidth();
},
calLeftBtnsWidth() {
var that = this;
this.$element('leftbtns').getBoundingClientRect({
success(res) {
let msg = JSON.stringify(res);
console.log('calLeftBtnsWidth 当前坐标:' + msg);
// that.leftbtnsWidth = res.width;
that.convertRealPx(true, res.width);
},
fail() {
console.log('calBoxWidth 获取失败');
},
complete() {
console.log('calBoxWidth complete')
}
})
},
calRightBtnsWidth() {
var that = this;
this.$element('rightbtns').getBoundingClientRect({
success(res) {
let msg = JSON.stringify(res);
console.log('calRightBtnsWidth 当前坐标:' + msg);
// that.rightbtnsWidth = res.width;
that.convertRealPx(false, res.width);
},
fail() {
console.log('calBoxWidth 获取失败');
},
complete() {
console.log('calBoxWidth complete')
}
})
},
convertRealPx(isLeftWidth, data) {
var d = device.getInfoSync();
console.info("calBannerPostion1 d= " + JSON.stringify(d));
//获取页面内可见窗口的高度和宽度,此值不包括标题栏和状态栏高度
let windowWidth = d.windowWidth;
//logicWidth对应manifest.json文件设置的designWidth值,默认是750
let logicWidth = d.windowLogicWidth;
let result = data * 1.0 * windowWidth / logicWidth;
if (isLeftWidth) {
this.leftbtnsWidth = result;
} else {
this.rightbtnsWidth = result;
}
},
dealTouchStart: function (e) {
if (this.disabled) {
return;
}
this.movestartX = e.touches[0].clientX;
console.info("dealTouchStart movestartX="+this.movestartX);
},
dealTouchMove: function (e) {
if (this.disabled) {
return;
}
let moveX = e.touches[0].clientX;
let dis = moveX - this.movestartX;
console.info("dealTouchMove moveX= " + moveX + ", dis=" + dis);
if (Math.abs(dis) < this.threshold) {
return;
}
if (dis > 0) {
//右滑动呼出左边的按钮或者隐藏右边按钮恢复初始状态
if (this.isRightOpened) {
//隐藏右边的按钮,恢复初始状态
this.animate(dis-this.rightbtnsWidth, dis);
} else {
//右滑动,呼出左边的按钮
if (this.leftbtnsWidth > 0) {
if (!this.isLeftOpened) {
console.info("begin to show the left buttons");
this.animate(dis, dis);
}
}
}
}
else if (dis < 0) {
console.info("dealTouchMove left this.isLeftOpened=" + this.isLeftOpened);
if (this.isLeftOpened) {
//慢慢滑动将左边按钮隐藏
this.animate(this.leftbtnsWidth + dis, dis);
} else {
//呼出右边的按钮
if (this.rightbtnsWidth > 0) {
if (!this.isRightOpened) {
console.info("dealTouchMove begin to show the right buttons");
this.animate(dis, dis);
}
}
}
}
},
dealTouchEnd: function (e) {
if (this.disabled) {
return;
}
let endX = e.changedTouches[0].clientX;
let dis = endX - this.movestartX;
if (Math.abs(dis) < this.threshold) {
return;
}
console.info("dealTouchEnd dis=" + dis + ", endX=" + endX + ", isLeftOpened=" + this.isLeftOpened + ",isRightOpened=" + this.isRightOpened);
if (dis > 0) {
//往右边滑动
if (this.isRightOpened) {
//隐藏右边按钮
this.animate(dis - this.rightbtnsWidth, 0);
this.isRightOpened = false;
this.$emit('swipestatechange', {params: {"isOpened":false}});
} else {
if (!this.isLeftOpened) {
//呼出左边按钮,将左边按钮完整显示出来;
if (this.leftbtnsWidth > 0) {
this.animate(dis, this.leftbtnsWidth);
this.isLeftOpened = true;
this.$emit('swipestatechange', {params: {"isOpened":true}});
}
}
}
} else if (dis < 0) {
//往左滑动
if (this.isLeftOpened) {
//隐藏左边按钮
this.animate(this.leftbtnsWidth + dis, 0);
this.isLeftOpened = false;
this.$emit('swipestatechange', {params: {"isOpened":false}});
} else {
if (this.rightbtnsWidth > 0 && !this.isRightOpened) {
//呼出右边按钮,将右边按钮完整显示出来
this.animate(dis, -this.rightbtnsWidth);
this.isRightOpened = true;
this.$emit('swipestatechange', {params: {"isOpened":true}});
}
}
}
},
animate(value1, value2) {
console.info("aninate translateX from: " + value1 + ", to:" + value2);
let cmp = this.$element('swipe_item');
var options = {
duration: 300, easing: 'linear',
delay: 0,
fill: 'forwards'
}
console.info("dealTouchMove value2=" + value2);
var frames = [
{
transform: {
translateX: value1,
}
},
{
transform: {
translateX: value2,
}
}];
var animation = cmp.animate(frames, options);
animation.play();
animation.onfinish = function () {
console.log("animation onfinish");
}
animation.oncancel = function () {
console.log("animation oncancel");
}
},
btnsClick: function(index,direction,btnValue) {
console.info("swipe.ux item click direction="+direction);
this.$emit('swipebtnclick', {params: {"clickIndex":index,"position":direction,"btnValue":btnValue}});
//按钮关闭
if(direction=='left'){
this.animate(this.leftbtnsWidth, 0);
this.isLeftOpened = false;
}else{
this.animate( - this.rightbtnsWidth, 0);
this.isRightOpened = false;
}
this.$emit('swipestatechange', {params: {"isOpened":false}});
},
close:function() {
if(this.isLeftOpened){
//关闭
this.animate(this.leftbtnsWidth, 0);
this.isLeftOpened = false;
this.$emit('swipestatechange', {params: {"isOpened":false}});
}else if(this.isRightOpened){
//关闭
this.animate( - this.rightbtnsWidth, 0);
this.isRightOpened = false;
this.$emit('swipestatechange', {params: {"isOpened":false}});
}else{
//中间部分响应自身的点击事件
this.$emit('centerclick', {params: {}});
}
},
closeFromParent:function(e) {
console.info("closeFromParent e="+JSON.stringify(e));
if(!this.autoClose){
return;
}
//最新滑动打开的操作栏不关闭,其他的才关闭
let excludeCloseId=e.detail.exclude;
if(excludeCloseId==this.identity){
return;
}
if(this.isLeftOpened){
//关闭
this.animate(this.leftbtnsWidth, 0);
this.isLeftOpened = false;
}else if(this.isRightOpened){
//关闭
this.animate( - this.rightbtnsWidth, 0);
this.isRightOpened = false;
}
},
dealClickCenter: function() {
console.info("dealClickCenter");
this.close();
},
}
</script>
页面main.ux
<import name="swipeitem" src="../Component/swipe_item.ux"></import>
<template>
<!-- Only one root node is allowed in template. -->
<div class="container">
<div class="section">
<text class="sec_txt">只有左边</text>
</div>
<swipeitem identity='111' left-options="{{leftBtns}}" @swipebtnclick="swipeItemClick" @swipestatechange="swipeItemChange('111')">
<text>只有左边按钮</text>
</swipeitem>
<div class="section">
<text class="sec_txt">只有右边</text>
</div>
<swipeitem identity='112' right-options="{{rightBtns}}" @swipebtnclick="swipeItemClick" @swipestatechange="swipeItemChange('112')">
<text>只有右边按钮</text>
</swipeitem>
<div class="section">
<text class="sec_txt">混合滚动</text>
</div>
<swipeitem identity='113' right-options="{{rightBtns}}" left-options="{{leftBtns}}" @swipebtnclick="swipeItemClick" @swipestatechange="swipeItemChange('113')">
<text>左右都有混合滚动</text>
</swipeitem>
<div class="section">
<text class="sec_txt">禁止左右滚动</text>
</div>
<swipeitem disabled="{{disabled}}" left-options="{{leftBtns}}" right-options="{{rightBtns}}" @swipebtnclick="swipeItemClick">
<text>禁止左右滚动</text>
</swipeitem>
<div class="section">
<text class="sec_txt">div列表</text>
</div>
<div class="swipelist" id="swiplist">
<swipeitem identity="{{item.id}}" auto-close={{isautoclose}} right-options="{{item.options}}" for="(index,item) in swipeList" @swipestatechange="listSwipeItemChange(index)"
@swipebtnclick="listSwipeItemClick(index)" @centerclick="listCenterItemClick(index)">
<text onclick="clickText">{{item.content}}</text>
</swipeitem>
</div>
</div>
</template>
<style>
.container {
flex-direction: column;
width: 100%;
}
.section {
background-color: #f5f5f5;
height: 100px;
width: 100%;
border: 1px solid #f5f5f5;
}
.swipelist {
flex-direction: column;
}
.istItemStyle {
width: 1300px;
}
.liststyle {
flex-direction: column;
}
.sec_txt {
font-size: 32px;
font-weight: 600;
margin-left: 25px;
margin-top: 10px;
}
</style>
<script>
import prompt from '@system.prompt';
module.exports = {
data: {
isautoclose:true,
leftBtns: [],
disabled: true,
rightBtns: [],
unstyleleftBtns: [],
unstylerightBtns: [],
swipeList: []
},
onInit: function () {
let btn1 = { "txt": "置顶", "style": { "backgroundColor": "#00bfff", "txtColor": "#dcdcdc", "fontsize": 30, "btnwidth": 150 } };
let btn2 = { "txt": "ok", "style": { "backgroundColor": "#00bfff", "txtColor": "#dcdcdc", "fontsize": 30, "btnwidth": 200 } };
let btn3 = { "txt": "取消置顶", "style": { "backgroundColor": "#f01f1f", "txtColor": "#dcdcdc", "fontsize": 30, "btnwidth": 150 } };
let btn4 = { "txt": "cancel", "style": { "backgroundColor": "#00bfff", "txtColor": "#dcdcdc", "fontsize": 30, "btnwidth": 180 } };
let unstylebtn1 = { "txt": "置顶", "style": { "btnwidth": 230 } };
let unstylebtn2 = { "txt": "ok", "style": { "btnwidth": 200 } };
let unstylebtn3 = { "txt": "取消置顶", "style": { "btnwidth": 150 } };
let unstylebtn4 = { "txt": "cancel", "style": { "txtColor": "#ff9900", "fontsize": 30, "btnwidth": 150 } };
this.leftBtns.push(btn1);
this.leftBtns.push(btn2);
this.rightBtns.push(btn3);
this.rightBtns.push(btn4);
this.unstyleleftBtns.push(unstylebtn1);
this.unstyleleftBtns.push(unstylebtn2);
this.unstylerightBtns.push(unstylebtn3);
this.unstylerightBtns.push(unstylebtn4);
},
onReady(options) {
this.swipeList = [{
options: [{
txt: '添加',
style: {
backgroundColor: 'rgb(255,58,49)',
txtColor: "#dcdcdc",
fontsize: 36,
btnwidth: 150
}
}],
id: '10',
content: 'item1'
},
{
id: '11',
options: [{
txt: '添加',
style: {
backgroundColor: 'rgb(255,58,49)',
txtColor: "#dcdcdc",
fontsize: 30,
btnwidth: 150
}
},
{
txt: '删除',
style: {
backgroundColor: 'rgb(255,58,49)',
txtColor: "#dcdcdc",
fontsize: 30,
btnwidth: 150
}
}
],
content: 'item2'
},
{
id: '12',
options: [{
txt: '置顶',
style: {
backgroundColor: 'rgb(255,58,49)',
txtColor: "#dcdcdc",
fontsize: 30,
btnwidth: 150
}
},
{
txt: '标记为已读',
style: {
backgroundColor: 'rgb(255,58,49)',
txtColor: "#dcdcdc",
fontsize: 30,
btnwidth: 150
}
},
{
txt: '删除',
style: {
backgroundColor: 'rgb(255,58,49)',
txtColor: "#dcdcdc",
fontsize: 30,
btnwidth: 150
}
}
],
content: 'item3'
}
]
},
listSwipeItemClick: function (index, e) {
console.info("main swipeItemClick e:" + JSON.stringify(e) + ",index=" + index);
let position = e.detail.params.position;
// // let index = e.detail.params.clickIndex;
// let itemListId = e.detail.params.itemListIndex;
let btnValue = e.detail.params.btnValue;
let msg = '';
if (position == 'left') {
// msg='点击了左侧 ${e.detail.params.btnValue}按钮 ' ;
msg = '点击了左侧' + btnValue + '按钮 ';
} else {
msg = '点击了右侧' + btnValue + '按钮 ';
}
prompt.showToast({
message: msg,
duration: 2000,
gravity: 'center'
})
if (btnValue == "添加") {
console.info("begin to add ")
this.addSwipteItem();
} else if (btnValue == "删除") {
this.delSwipteItem(index);
}
},
addSwipteItem: function () {
this.swipeList.push({
id: new Date().getTime(),
content: '新增' + new Date().getTime(),
options: [{
txt: '置顶',
style: {
fontsize: 30,
btnwidth: 150
}
},
{
txt: '标记为已读',
style: {
backgroundColor: 'rgb(254,156,1)',
fontsize: 30,
btnwidth: 150
}
},
{
txt: '删除',
style: {
backgroundColor: 'rgb(255,58,49)',
fontsize: 30,
btnwidth: 150
}
}
],
});
},
delSwipteItem: function (index) {
var that = this;
prompt.showDialog({
title: '提示',
message: '是否删除',
buttons: [
{
text: '确定',
color: '#33dd44'
}, {
text: '取消',
color: '#33dd44'
}],
success: function (data) {
console.log("delSwipteItem showDialog handling callback data:" + JSON.stringify(data));
if (data.index == 0) {
//delete
that.swipeList.splice(index, 1);
}
},
fail: function (data, code) {
console.log("handling fail, code = " + code);
}
})
},
swipeItemClick: function (e) {
console.info("main swipeItemClick e:" + JSON.stringify(e));
let position = e.detail.params.position;
let btnValue = e.detail.params.btnValue;
let msg = '';
if (position == 'left') {
// msg='点击了左侧 ${e.detail.params.btnValue}按钮 ' ;
msg = '点击了左侧' + btnValue + '按钮 ';
} else {
msg = '点击了右侧' + btnValue + '按钮 ';
}
prompt.showToast({
message: msg,
duration: 2000,
gravity: 'center'
})
},
clickText: function () {
console.info("click text");
prompt.showToast({
message: 'click text',
duration: 2000,
gravity: 'center'
})
},
listCenterItemClick: function (index, e) {
console.info("main listCenterItemClick e:" + JSON.stringify(e) + ",index=" + index);
prompt.showToast({
message: 'click text',
duration: 2000,
gravity: 'center'
})
},
listSwipeItemChange: function (index, e) {
console.info("main listSwipeItemChange e:" + JSON.stringify(e) + ",index=" + index);
this.$broadcast('closeSwipeItem', { 'exclude': this.swipeList[index].id });
},
swipeItemChange: function(id,e) {
console.info("main swipeItemChange e:" + JSON.stringify(e)+",id="+id);
this.$broadcast('closeSwipeItem', { 'exclude': id });
},
}
</script>
欲了解更多更全技术文章,欢迎访问https://developer.huawei.com/consumer/cn/forum/?ha_source=zzh