|
@@ -0,0 +1,194 @@
|
|
|
+<template>
|
|
|
+ <view class="next-slide" :class="{'next-slide-disabled': disabled}">
|
|
|
+ <view class="next-slide-left" :style="'position: relative;left:'+left+'rpx'" @touchstart="ontouchstart"
|
|
|
+ @touchmove="ontouchmove" @touchend="ontouchend">
|
|
|
+ <slot></slot>
|
|
|
+ </view>
|
|
|
+ <view class="next-slide-right">
|
|
|
+ <view
|
|
|
+ class="next-btn-item"
|
|
|
+ v-for="(item,index) in btnGroup"
|
|
|
+ :key="index"
|
|
|
+ :style="getStyle(item)"
|
|
|
+ @click.stop="btnClick(item)">
|
|
|
+ {{item.name }}
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+ const defBtnStyle = {
|
|
|
+ width: '100rpx',
|
|
|
+ bgColor: '#f9ae3d',
|
|
|
+ color: '#FFFFFF',
|
|
|
+ fontSize: '28rpx',
|
|
|
+ fontWeight: 300
|
|
|
+ };
|
|
|
+
|
|
|
+ export default {
|
|
|
+ name: 'NextSwipeAction',
|
|
|
+ props: {
|
|
|
+ btnGroup: {
|
|
|
+ type: Array,
|
|
|
+ default: () => {
|
|
|
+ return [{
|
|
|
+ name: '修改',
|
|
|
+ style: {
|
|
|
+ bgColor: '#f9ae3d'
|
|
|
+ }
|
|
|
+ }, {
|
|
|
+ name: '删除',
|
|
|
+ style: {
|
|
|
+ bgColor: '#ff4d4f'
|
|
|
+ }
|
|
|
+ }]
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //当前列索引
|
|
|
+ index: {
|
|
|
+ type: [Number,String],
|
|
|
+ require: true,
|
|
|
+ default: 0
|
|
|
+ },
|
|
|
+ activeKey:{
|
|
|
+ type: [Number,String],
|
|
|
+ default:''
|
|
|
+ },
|
|
|
+ //是否禁用
|
|
|
+ disabled: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ },
|
|
|
+ // 是否按钮点击后自定重置
|
|
|
+ btnClickAutoReset: {
|
|
|
+ type: Boolean,
|
|
|
+ default: true
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ x: 0,
|
|
|
+ left: 0,
|
|
|
+ operation: 0,
|
|
|
+ height: 0,
|
|
|
+ screenWidth: 0,
|
|
|
+ isActive:false,
|
|
|
+ };
|
|
|
+ },
|
|
|
+ watch:{
|
|
|
+ activeKey(newV){
|
|
|
+ if(!this.isActive)return;
|
|
|
+ if(newV != this.index){
|
|
|
+ this.reset()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.$nextTick(res => {
|
|
|
+ const systemInfo = uni.getSystemInfoSync()
|
|
|
+ this.screenWidth = systemInfo.screenWidth
|
|
|
+ this.getBtnWidth()
|
|
|
+ this.getListHeight()
|
|
|
+ })
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ getStyle(item) {
|
|
|
+ const style = item.style || {};
|
|
|
+ const styleStr = 'width:'+ (style.width || defBtnStyle.width) +
|
|
|
+ ';height:' + this.height +
|
|
|
+ 'rpx;background-color:' + (style.bgColor || defBtnStyle.bgColor) +
|
|
|
+ ';color:' + (style.color || defBtnStyle.color) +
|
|
|
+ ';font-size:' + (style.fontSize || defBtnStyle.fontSize) +
|
|
|
+ 'font-weight:' + (style.fontWeight || defBtnStyle.fontWeight);
|
|
|
+ return styleStr
|
|
|
+ },
|
|
|
+ btnClick(item) {
|
|
|
+ const it = Object.assign({}, item);
|
|
|
+ delete it.style;
|
|
|
+ this.$emit('btnClick', {
|
|
|
+ index: this.index,
|
|
|
+ item: it
|
|
|
+ })
|
|
|
+ if(this.btnClickAutoReset) {
|
|
|
+ this.reset()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //重置方法
|
|
|
+ reset() {
|
|
|
+ this.left = 0
|
|
|
+ this.isActive = false;
|
|
|
+ },
|
|
|
+ getBtnWidth() {
|
|
|
+ const element = uni.createSelectorQuery().in(this).select(".next-slide-right");
|
|
|
+ element.boundingClientRect(rect => {
|
|
|
+ this.operation = this.px2rpx(rect.width, this.screenWidth)
|
|
|
+ }).exec()
|
|
|
+ },
|
|
|
+ getListHeight() {
|
|
|
+ const element = uni.createSelectorQuery().in(this).select(".next-slide-left");
|
|
|
+ element.boundingClientRect(rect => {
|
|
|
+ this.height = this.px2rpx(rect.height, this.screenWidth)
|
|
|
+ }).exec()
|
|
|
+ },
|
|
|
+ px2rpx(px, screenWidth) {
|
|
|
+ return px / (screenWidth / 750)
|
|
|
+ },
|
|
|
+ ontouchstart(e) {
|
|
|
+ if(this.disabled) return
|
|
|
+ this.x = this.px2rpx(e.touches[0].clientX, this.screenWidth)
|
|
|
+ },
|
|
|
+ ontouchmove(e) {
|
|
|
+ if(this.disabled) return
|
|
|
+ let clientX = this.x - this.px2rpx(e.touches[0].clientX, this.screenWidth)
|
|
|
+ if (clientX <= 0) this.left = 0
|
|
|
+ else if (this.operation <= clientX) this.left = this.operation * -1
|
|
|
+ else this.left = clientX * -1
|
|
|
+ },
|
|
|
+ ontouchend(e) {
|
|
|
+ if(this.disabled) return
|
|
|
+ let clientX = this.x - this.px2rpx(e.changedTouches[0].clientX, this.screenWidth)
|
|
|
+ this.left = clientX > this.operation / 2 ? this.operation * -1 : 0
|
|
|
+ if(this.left !== 0){
|
|
|
+ this.isActive = true;
|
|
|
+ this.$emit('nextSwipeActive', this.index)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ }
|
|
|
+ }
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+ .next-slide {
|
|
|
+ width: 100%;
|
|
|
+ position: relative;
|
|
|
+ overflow: hidden;
|
|
|
+ }
|
|
|
+ .next-slide-disabled {
|
|
|
+ background-color: #333333;
|
|
|
+ opacity: 0.6;
|
|
|
+ }
|
|
|
+ .next-slide-left {
|
|
|
+ width: 100%;
|
|
|
+ overflow: hidden;
|
|
|
+ background-color: #161616;
|
|
|
+ transition: left 0.2s ease-in-out;
|
|
|
+ z-index: 999;
|
|
|
+ }
|
|
|
+
|
|
|
+ .next-slide-right {
|
|
|
+ position: absolute;
|
|
|
+ top: 0rpx;
|
|
|
+ right: 0;
|
|
|
+ z-index: 99;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: flex-end;
|
|
|
+ }
|
|
|
+
|
|
|
+ .next-btn-item {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ }
|
|
|
+</style>
|