feat: 首次提交
This commit is contained in:
226
components/firstui/fui-swipe-action/bindingx.js
Normal file
226
components/firstui/fui-swipe-action/bindingx.js
Normal file
@ -0,0 +1,226 @@
|
||||
// 本文件由FirstUI授权予新疆天衡创新研究院有限公司(手机号: 1861 4 07 2 5 4 9,身份证尾号:5A07X5)专用,请尊重知识产权,勿私下传播,违者追究法律责任。
|
||||
// #ifdef APP-NVUE
|
||||
const BindingX = uni.requireNativePlugin('bindingx');
|
||||
const dom = uni.requireNativePlugin('dom');
|
||||
const animation = uni.requireNativePlugin('animation');
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
watch: {
|
||||
show(newVal) {
|
||||
// if (this.autoClose) return
|
||||
if (this.stop) return
|
||||
this.stop = true
|
||||
if (newVal) {
|
||||
this.open(newVal)
|
||||
} else {
|
||||
this.close()
|
||||
}
|
||||
},
|
||||
buttons(newVal) {
|
||||
this.init()
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.group = this.getParent()
|
||||
if (this.group.children !== undefined) {
|
||||
this.group.children.push(this)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(()=>{
|
||||
this.box = this.getEl(this.$refs['fui_swipea_wrap'])
|
||||
this.selector = this.getEl(this.$refs['fui_swipea_content']);
|
||||
this.rightButton = this.getEl(this.$refs['fui_swipea_buttons']);
|
||||
})
|
||||
this.init()
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.$nextTick(() => {
|
||||
this.x = 0
|
||||
this.button = {
|
||||
show: false
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.getSelectorQuery()
|
||||
}, 200)
|
||||
})
|
||||
},
|
||||
handleClick(e, index, item) {
|
||||
e.stopPropagation();
|
||||
this.$emit('click', {
|
||||
item,
|
||||
index,
|
||||
param: this.param
|
||||
})
|
||||
},
|
||||
touchstart(e) {
|
||||
if (this.disabled) return
|
||||
// 每次只触发一次,避免多次监听造成闪烁
|
||||
if (this.stop) return
|
||||
this.stop = true
|
||||
if (this.autoClose) {
|
||||
this.group && this.group.closeAuto(this)
|
||||
}
|
||||
|
||||
const rightWidth = this.button.right.width || 0
|
||||
let expression = this.range(this.x, -rightWidth, 0)
|
||||
let rightExpression = this.range(this.x + rightWidth, 0, rightWidth)
|
||||
|
||||
this.eventpan = BindingX.bind({
|
||||
anchor: this.box,
|
||||
eventType: 'pan',
|
||||
props: [{
|
||||
element: this.selector,
|
||||
property: 'transform.translateX',
|
||||
expression
|
||||
}, {
|
||||
element: this.rightButton,
|
||||
property: 'transform.translateX',
|
||||
expression: rightExpression
|
||||
}]
|
||||
}, (e) => {
|
||||
if (e.state === 'end') {
|
||||
this.x = e.deltaX + this.x;
|
||||
this.isclick = true
|
||||
this.bindTiming(e.deltaX)
|
||||
}
|
||||
});
|
||||
},
|
||||
touchend(e) {
|
||||
if (this.isopen && !this.isclick) {
|
||||
this.open(false)
|
||||
}
|
||||
},
|
||||
bindTiming(x) {
|
||||
const left = this.x
|
||||
const rightWidth = this.button.right.width || 0
|
||||
const threshold = Number(this.threshold)
|
||||
if (!this.isopen) {
|
||||
if (left < -threshold) {
|
||||
this.open(true)
|
||||
} else {
|
||||
this.open(false)
|
||||
}
|
||||
} else {
|
||||
if ((x < threshold && x > 0) || (x < -threshold)) {
|
||||
this.open(true)
|
||||
} else {
|
||||
this.open(false)
|
||||
}
|
||||
}
|
||||
},
|
||||
range(num, mix, max) {
|
||||
return `min(max(x+${num}, ${mix}), ${max})`
|
||||
},
|
||||
open(type) {
|
||||
this.animation(type)
|
||||
},
|
||||
close() {
|
||||
this.animation(false)
|
||||
},
|
||||
animation(type) {
|
||||
const time = 300
|
||||
const rightWidth = this.button.right.width || 0
|
||||
if (this.eventpan && this.eventpan.token) {
|
||||
BindingX.unbind({
|
||||
token: this.eventpan.token,
|
||||
eventType: 'pan'
|
||||
})
|
||||
}
|
||||
|
||||
if (type) {
|
||||
Promise.all([
|
||||
this.move(this.selector, -rightWidth),
|
||||
this.move(this.rightButton, 0)
|
||||
]).then(() => {
|
||||
this.setEmit(-rightWidth, type)
|
||||
})
|
||||
} else {
|
||||
Promise.all([
|
||||
this.move(this.selector, 0),
|
||||
this.move(this.rightButton, rightWidth)
|
||||
]).then(() => {
|
||||
this.setEmit(0, type)
|
||||
})
|
||||
}
|
||||
},
|
||||
setEmit(x, type) {
|
||||
const rightWidth = this.button.right.width
|
||||
this.isopen = this.isopen || false
|
||||
this.stop = false
|
||||
this.isclick = false
|
||||
if (this.isopen !== type && this.x !== x) {
|
||||
if (type && rightWidth > 0) {
|
||||
this.$emit('change', {
|
||||
isOpen: true,
|
||||
param: this.param
|
||||
})
|
||||
}
|
||||
if (!type) {
|
||||
this.$emit('change', {
|
||||
isOpen: false,
|
||||
param: this.param
|
||||
})
|
||||
}
|
||||
}
|
||||
this.x = x
|
||||
this.isopen = type
|
||||
},
|
||||
move(ref, value) {
|
||||
return new Promise((resolve, reject) => {
|
||||
animation.transition(ref, {
|
||||
styles: {
|
||||
transform: `translateX(${value})`,
|
||||
},
|
||||
duration: 150, //ms
|
||||
timingFunction: 'linear',
|
||||
needLayout: false,
|
||||
delay: 0 //ms
|
||||
}, function(res) {
|
||||
resolve(res)
|
||||
})
|
||||
})
|
||||
|
||||
},
|
||||
getEl(el) {
|
||||
return el.ref
|
||||
},
|
||||
getSelectorQuery() {
|
||||
Promise.all([
|
||||
this.getDom(),
|
||||
]).then((data) => {
|
||||
// let show = false
|
||||
// if (!this.autoClose) {
|
||||
// show = this.show
|
||||
// }
|
||||
// if (show) {
|
||||
// this.open(show)
|
||||
// }
|
||||
this.open(this.show)
|
||||
})
|
||||
|
||||
},
|
||||
getDom() {
|
||||
return new Promise((resolve, reject) => {
|
||||
dom.getComponentRect(this.$refs['fui_swipea_buttons'], (data) => {
|
||||
if (data) {
|
||||
this.button['right'] = data.size
|
||||
resolve(data)
|
||||
} else {
|
||||
reject()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// #endif
|
||||
|
||||
// #ifndef APP-NVUE
|
||||
export default {}
|
||||
// #endif
|
234
components/firstui/fui-swipe-action/fui-swipe-action.vue
Normal file
234
components/firstui/fui-swipe-action/fui-swipe-action.vue
Normal file
@ -0,0 +1,234 @@
|
||||
<!--本文件由FirstUI授权予新疆天衡创新研究院有限公司(手机号: 186 140 7 2 54 9,身份证尾号:5A07X5)专用,请尊重知识产权,勿私下传播,违者追究法律责任。-->
|
||||
<template>
|
||||
<!-- #ifdef APP-VUE || MP-WEIXIN || H5 -->
|
||||
<view class="fui-swipe__action-wrap" :style="{marginTop:marginTop+'rpx',marginBottom:marginBottom+'rpx'}">
|
||||
<view class="fui-swipe__action-inner" :show="isShow" :change:show="handler.showChange" :threshold="thresholdVal"
|
||||
:change:threshold="handler.thresholdChange" :disabled="isDisabled" :change:disabled="handler.disabledChange"
|
||||
@touchstart="handler.touchstart" @touchmove="handler.touchmove" @touchend="handler.touchend"
|
||||
@mousedown="handler.mousedown" @mousemove="handler.mousemove" @mouseup="handler.mouseup"
|
||||
@mouseleave="handler.mouseleave">
|
||||
<view class="fui-swipe__action-left">
|
||||
<slot></slot>
|
||||
</view>
|
||||
<view class="fui-swipe__action-right">
|
||||
<slot name="buttons">
|
||||
<view class="fui-swipe__action-btn" :style="{background:item.background}"
|
||||
v-for="(item,index) in buttons" :key="index" @touchstart="appTouchStart"
|
||||
@touchend="appTouchEnd($event,index,item)" @tap.stop="handleClick(index,item)">
|
||||
<text class="fui-swipe__action-text"
|
||||
:style="{fontSize:(item.size || size)+'rpx',color:item.color || color}">{{item.text}}</text>
|
||||
</view>
|
||||
</slot>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
|
||||
<!-- #ifdef APP-NVUE -->
|
||||
<view class="fui-swipe__action-wrap" :style="{marginTop:marginTop+'rpx',marginBottom:marginBottom+'rpx'}"
|
||||
ref="fui_swipea_wrap" @horizontalpan="touchstart" @touchend="touchend">
|
||||
<view class="fui-swipe__action-right" ref="fui_swipea_buttons">
|
||||
<slot name="buttons">
|
||||
<view class="fui-swipe__action-btn" :style="{background:item.background}"
|
||||
v-for="(item,index) in buttons" :key="index" @tap.stop="handleClick($event,index,item)">
|
||||
<text class="fui-swipe__action-text"
|
||||
:style="{fontSize:(item.size || size)+'rpx',color:item.color || color}">{{item.text}}</text>
|
||||
</view>
|
||||
</slot>
|
||||
</view>
|
||||
<view class="fui-swipe__action-left" ref="fui_swipea_content">
|
||||
<slot></slot>
|
||||
</view>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
|
||||
<!-- #ifndef APP-PLUS|| MP-WEIXIN || H5 -->
|
||||
<view class="fui-swipe__action-wrap" :style="{marginTop:marginTop+'rpx',marginBottom:marginBottom+'rpx'}">
|
||||
<view class="fui-swipe__action-inner" @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend"
|
||||
:style="{transform:moveLeft}" :class="{'fui-swipe__action-ani':ani}">
|
||||
<view class="fui-swipe__action-left">
|
||||
<slot></slot>
|
||||
</view>
|
||||
<view class="fui-swipe__action-right" :class="[elClass]">
|
||||
<slot name="buttons">
|
||||
<view class="fui-swipe__action-btn" :style="{background:item.background}"
|
||||
v-for="(item,index) in buttons" :key="index" @touchstart="appTouchStart"
|
||||
@touchend="appTouchEnd($event,index,item)">
|
||||
<text class="fui-swipe__action-text"
|
||||
:style="{fontSize:(item.size || size)+'rpx',color:item.color || color}">{{item.text}}</text>
|
||||
</view>
|
||||
</slot>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
|
||||
</template>
|
||||
<!-- #ifdef APP-VUE || MP-WEIXIN || H5 -->
|
||||
<script src="./index.wxs" module="handler" lang="wxs"></script>
|
||||
<!-- #endif -->
|
||||
|
||||
<script>
|
||||
import mpwxs from './mpwxs.js'
|
||||
import mpjs from './mpjs.js'
|
||||
import bindingx from './bindingx.js'
|
||||
const dangerColor = (uni && uni.$fui && uni.$fui.color && uni.$fui.color.danger) || '#FF2B2B'
|
||||
export default {
|
||||
name: "fui-swipe-action",
|
||||
mixins: [mpwxs, mpjs, bindingx],
|
||||
emits: ['click', 'change'],
|
||||
props: {
|
||||
buttons: {
|
||||
type: Array,
|
||||
default () {
|
||||
return [{
|
||||
text: '删除',
|
||||
background: dangerColor
|
||||
}]
|
||||
}
|
||||
},
|
||||
size: {
|
||||
type: [Number, String],
|
||||
default: 32
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: '#fff'
|
||||
},
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
threshold: {
|
||||
type: [Number, String],
|
||||
default: 30
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
autoClose: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
//1.9.9+
|
||||
marginTop: {
|
||||
type: [Number, String],
|
||||
default: 0
|
||||
},
|
||||
//1.9.9+
|
||||
marginBottom: {
|
||||
type: [Number, String],
|
||||
default: 0
|
||||
},
|
||||
param: {
|
||||
type: [Number, String],
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
// #ifndef VUE3
|
||||
beforeDestroy() {
|
||||
if (this.__beforeUnmount) return
|
||||
this.unInstall()
|
||||
},
|
||||
// #endif
|
||||
// #ifdef VUE3
|
||||
beforeUnmount() {
|
||||
this.__beforeUnmount = true;
|
||||
this.unInstall()
|
||||
},
|
||||
// #endif
|
||||
methods: {
|
||||
unInstall() {
|
||||
if (this.group) {
|
||||
this.group.children.forEach((item, index) => {
|
||||
if (item === this) {
|
||||
this.group.children.splice(index, 1)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
//获取父元素实例
|
||||
getParent(name = 'fui-swipeaction-group') {
|
||||
let parent = this.$parent;
|
||||
let parentName = parent.$options.name;
|
||||
while (parentName !== name) {
|
||||
parent = parent.$parent;
|
||||
if (!parent) return false;
|
||||
parentName = parent.$options.name;
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.fui-swipe__action-wrap {
|
||||
position: relative;
|
||||
/* #ifndef APP-NVUE */
|
||||
overflow: hidden;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.fui-swipe__action-inner {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
/* #endif */
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.fui-swipe__action-left {
|
||||
/* #ifndef APP-NVUE */
|
||||
width: 100%;
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
/* #endif */
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.fui-swipe__action-right {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: inline-flex;
|
||||
box-sizing: border-box;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
/* #ifdef H5 */
|
||||
cursor: pointer;
|
||||
/* #endif */
|
||||
transform: translateX(100%);
|
||||
}
|
||||
|
||||
.fui-swipe__action-btn {
|
||||
/* #ifdef APP-NVUE */
|
||||
flex: 1;
|
||||
/* #endif */
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 0 48rpx;
|
||||
/* #ifdef H5 */
|
||||
cursor: pointer;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.fui-swipe__action-text {
|
||||
/* #ifndef APP-NVUE */
|
||||
flex-shrink: 0;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.fui-swipe__action-ani {
|
||||
transition-property: transform;
|
||||
transition-duration: 0.3s;
|
||||
transition-timing-function: cubic-bezier(0.165, 0.84, 0.44, 1);
|
||||
}
|
||||
</style>
|
244
components/firstui/fui-swipe-action/index.wxs
Normal file
244
components/firstui/fui-swipe-action/index.wxs
Normal file
@ -0,0 +1,244 @@
|
||||
// 本文件由FirstUI授权予新疆天衡创新研究院有限公司(手机号:1 8 61 40 725 4 9,身份证尾号:5A07X5)专用,请尊重知识产权,勿私下传播,违者追究法律责任。
|
||||
var MIN_DISTANCE = 10
|
||||
|
||||
function isPC() {
|
||||
if (typeof navigator !== 'object') return false;
|
||||
var userAgentInfo = navigator.userAgent;
|
||||
var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
|
||||
var flag = true;
|
||||
for (var v = 0; v < Agents.length - 1; v++) {
|
||||
if (userAgentInfo.indexOf(Agents[v]) > 0) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
var isH5 = false
|
||||
if (typeof window === 'object') isH5 = true
|
||||
|
||||
function getDom(ins, ownerInstance) {
|
||||
var state = ins.getState()
|
||||
var rightDom = ownerInstance.selectComponent('.fui-swipe__action-right')
|
||||
if (!rightDom) {
|
||||
state.rightWidth = 0;
|
||||
return;
|
||||
}
|
||||
if (isH5 || isPC()) {
|
||||
if (rightDom['$el']) {
|
||||
state.rightWidth = rightDom['$el'].offsetWidth || 0
|
||||
} else {
|
||||
state.rightWidth = 0
|
||||
}
|
||||
} else {
|
||||
var rightStyles = rightDom.getBoundingClientRect()
|
||||
state.rightWidth = rightStyles.width || 0
|
||||
}
|
||||
}
|
||||
|
||||
function getDirection(x, y) {
|
||||
if (x > y && x > MIN_DISTANCE) {
|
||||
return 'horizontal';
|
||||
}
|
||||
if (y > x && y > MIN_DISTANCE) {
|
||||
return 'vertical';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function stopTouchMove(event) {
|
||||
var instance = event.instance;
|
||||
var state = instance.getState();
|
||||
var touch = event.touches[0];
|
||||
if (isH5 && isPC()) {
|
||||
touch = event;
|
||||
}
|
||||
state.deltaX = touch.clientX - state.startX;
|
||||
state.deltaY = touch.clientY - state.startY;
|
||||
state.offsetY = Math.abs(state.deltaY);
|
||||
state.offsetX = Math.abs(state.deltaX);
|
||||
state.direction = state.direction || getDirection(state.offsetX, state.offsetY);
|
||||
}
|
||||
|
||||
function stopTouchStart(event) {
|
||||
var instance = event.instance;
|
||||
var state = instance.getState();
|
||||
resetTouchStatus(instance);
|
||||
var touch = event.touches[0];
|
||||
if (isH5 && isPC()) {
|
||||
touch = event;
|
||||
}
|
||||
state.startX = touch.clientX;
|
||||
state.startY = touch.clientY;
|
||||
}
|
||||
|
||||
function touchstart(e, ownerInstance) {
|
||||
var ins = e.instance;
|
||||
var state = ins.getState();
|
||||
getDom(ins, ownerInstance)
|
||||
if (state.disabled) return
|
||||
// 开始触摸时移除动画类
|
||||
ins.requestAnimationFrame(function() {
|
||||
ins.removeClass('fui-swipe__action-ani');
|
||||
ownerInstance.callMethod('closeSwipe');
|
||||
})
|
||||
|
||||
// 记录上次的位置
|
||||
state.x = state.left || 0
|
||||
// 计算滑动开始位置
|
||||
stopTouchStart(e, ownerInstance)
|
||||
}
|
||||
|
||||
function move(value, ins, ownerInstance) {
|
||||
value = value || 0
|
||||
var state = ins.getState()
|
||||
var rightWidth = state.rightWidth
|
||||
// 获取可滑动范围
|
||||
state.left = Math.min(Math.max(value, -rightWidth), 0);
|
||||
ins.requestAnimationFrame(function() {
|
||||
ins.setStyle({
|
||||
transform: 'translateX(' + state.left + 'px)',
|
||||
'-webkit-transform': 'translateX(' + state.left + 'px)'
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function touchmove(e, ownerInstance) {
|
||||
var ins = e.instance;
|
||||
var state = ins.getState()
|
||||
if (state.disabled) return;
|
||||
// 是否可以滑动页面
|
||||
stopTouchMove(e);
|
||||
if (state.direction !== 'horizontal') return;
|
||||
|
||||
if (e.preventDefault) {
|
||||
// 阻止页面滚动
|
||||
e.preventDefault()
|
||||
}
|
||||
|
||||
move(state.x + state.deltaX, ins, ownerInstance)
|
||||
}
|
||||
|
||||
function openState(type, ins, ownerInstance) {
|
||||
var state = ins.getState()
|
||||
var leftWidth = state.leftWidth
|
||||
var rightWidth = state.rightWidth
|
||||
var left = ''
|
||||
state.open = state.open ? state.open : 'none'
|
||||
if (type === 'right' || type === true) {
|
||||
left = -rightWidth
|
||||
} else {
|
||||
left = 0
|
||||
}
|
||||
if (state.open !== type) {
|
||||
state.throttle = true
|
||||
ownerInstance.callMethod('change', {
|
||||
open: type
|
||||
})
|
||||
}
|
||||
|
||||
state.open = type
|
||||
// 添加动画类
|
||||
ins.requestAnimationFrame(function() {
|
||||
ins.addClass('fui-swipe__action-ani');
|
||||
move(left, ins, ownerInstance)
|
||||
})
|
||||
}
|
||||
|
||||
function moveDirection(left, ins, ownerInstance) {
|
||||
var state = ins.getState()
|
||||
var threshold = state.threshold || 30
|
||||
var position = state.position
|
||||
var open = state.open || 'none'
|
||||
var rightWidth = state.rightWidth
|
||||
if (state.deltaX === 0) {
|
||||
openState('none', ins, ownerInstance)
|
||||
return
|
||||
}
|
||||
if ((open === 'none' && rightWidth > 0 && -left > threshold) || (open !== 'none' && rightWidth > 0 &&
|
||||
rightWidth +
|
||||
left < threshold)) {
|
||||
openState('right', ins, ownerInstance)
|
||||
} else {
|
||||
// default
|
||||
openState('none', ins, ownerInstance)
|
||||
}
|
||||
}
|
||||
|
||||
function touchend(e, ownerInstance) {
|
||||
var instance = e.instance;
|
||||
var state = instance.getState()
|
||||
if (state.disabled) return
|
||||
moveDirection(state.left, instance, ownerInstance)
|
||||
}
|
||||
|
||||
function resetTouchStatus(instance) {
|
||||
var state = instance.getState();
|
||||
state.direction = '';
|
||||
state.deltaX = 0;
|
||||
state.deltaY = 0;
|
||||
state.offsetX = 0;
|
||||
state.offsetY = 0;
|
||||
}
|
||||
|
||||
function showChange(newVal, oldVal, ownerInstance, instance) {
|
||||
var state = instance.getState()
|
||||
getDom(instance, ownerInstance)
|
||||
if (newVal && newVal !== 'none') {
|
||||
openState(newVal || 'right', instance, ownerInstance)
|
||||
return
|
||||
}
|
||||
|
||||
if (state.left) {
|
||||
openState('none', instance, ownerInstance)
|
||||
}
|
||||
resetTouchStatus(instance)
|
||||
}
|
||||
|
||||
var movable = false
|
||||
|
||||
function mousedown(e, ins) {
|
||||
if (!isH5 || !isPC()) return
|
||||
touchstart(e, ins)
|
||||
movable = true
|
||||
}
|
||||
|
||||
function mousemove(e, ins) {
|
||||
if (!isH5 || !isPC() || !movable) return
|
||||
touchmove(e, ins)
|
||||
}
|
||||
|
||||
function mouseup(e, ins) {
|
||||
if (!isH5 || !isPC()) return
|
||||
touchend(e, ins)
|
||||
movable = false
|
||||
}
|
||||
|
||||
function mouseleave(e, ins) {
|
||||
if (!isH5 || !isPC()) return
|
||||
movable = false
|
||||
}
|
||||
|
||||
function disabledChange(newVal, oldVal, ownerInstance, ins) {
|
||||
var st = ins.getState()
|
||||
st.disabled = newVal
|
||||
}
|
||||
|
||||
function thresholdChange(newVal, oldVal, ownerInstance, ins) {
|
||||
var st = ins.getState()
|
||||
st.threshold = newVal || 30
|
||||
}
|
||||
|
||||
|
||||
module.exports = {
|
||||
touchstart: touchstart,
|
||||
touchmove: touchmove,
|
||||
touchend: touchend,
|
||||
mousedown: mousedown,
|
||||
mousemove: mousemove,
|
||||
mouseup: mouseup,
|
||||
mouseleave: mouseleave,
|
||||
disabledChange: disabledChange,
|
||||
thresholdChange: thresholdChange,
|
||||
showChange: showChange
|
||||
}
|
195
components/firstui/fui-swipe-action/mpjs.js
Normal file
195
components/firstui/fui-swipe-action/mpjs.js
Normal file
@ -0,0 +1,195 @@
|
||||
// 本文件由FirstUI授权予新疆天衡创新研究院有限公司(手机号: 1 86 140 7 2 549,身份证尾号:5A07X5)专用,请尊重知识产权,勿私下传播,违者追究法律责任。
|
||||
// #ifndef APP-PLUS|| MP-WEIXIN || H5
|
||||
|
||||
const MIN_DISTANCE = 10;
|
||||
export default {
|
||||
data() {
|
||||
const elClass = `fui_sa_${Math.ceil(Math.random() * 10e5).toString(36)}`
|
||||
return {
|
||||
left: 0,
|
||||
isShow: false,
|
||||
ani: false,
|
||||
moveLeft: '',
|
||||
elClass
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
show(newVal) {
|
||||
// if (this.autoClose) return
|
||||
this.openState(newVal)
|
||||
},
|
||||
left() {
|
||||
this.moveLeft = `translateX(${this.left}px)`
|
||||
},
|
||||
isShow(newVal) {
|
||||
// if (this.autoClose) return
|
||||
this.openState(newVal)
|
||||
},
|
||||
buttons() {
|
||||
this.init()
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(()=>{
|
||||
this.group = this.getParent()
|
||||
if (this.group.children !== undefined) {
|
||||
this.group.children.push(this)
|
||||
}
|
||||
this.init()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
clearTimeout(this.timer)
|
||||
this.timer = setTimeout(() => {
|
||||
this.getSelectorQuery()
|
||||
}, 100)
|
||||
this.left = 0
|
||||
this.x = 0
|
||||
},
|
||||
closeSwipe(e) {
|
||||
if (!this.autoClose) return
|
||||
this.group && this.group.closeAuto(this)
|
||||
},
|
||||
//解决 ios 13 点击区域错位的问题
|
||||
appTouchStart(e) {
|
||||
const {
|
||||
clientX
|
||||
} = e.changedTouches[0]
|
||||
this.clientX = clientX
|
||||
this.timestamp = new Date().getTime()
|
||||
},
|
||||
appTouchEnd(e, index, item) {
|
||||
const {
|
||||
clientX
|
||||
} = e.changedTouches[0]
|
||||
let diff = Math.abs(this.clientX - clientX)
|
||||
let time = (new Date().getTime()) - this.timestamp
|
||||
if (diff < 40 && time < 300) {
|
||||
this.$emit('click', {
|
||||
item,
|
||||
index,
|
||||
param: this.param
|
||||
})
|
||||
}
|
||||
},
|
||||
touchstart(e) {
|
||||
if (this.disabled) return
|
||||
this.ani = false
|
||||
this.x = this.left || 0
|
||||
this.stopTouchStart(e)
|
||||
this.autoClose && this.closeSwipe()
|
||||
},
|
||||
touchmove(e) {
|
||||
if (this.disabled) return
|
||||
// 是否可以滑动页面
|
||||
this.stopTouchMove(e);
|
||||
if (this.direction !== 'horizontal') {
|
||||
return;
|
||||
}
|
||||
this.move(this.x + this.deltaX)
|
||||
return false
|
||||
},
|
||||
touchend() {
|
||||
if (this.disabled) return
|
||||
this.moveDirection(this.left)
|
||||
},
|
||||
move(value) {
|
||||
value = value || 0
|
||||
const rightWidth = this.rightWidth
|
||||
this.left = Math.min(Math.max(value, -rightWidth), 0);
|
||||
},
|
||||
moveDirection(left) {
|
||||
const threshold = Number(this.threshold)
|
||||
const open = this.open || false
|
||||
const leftWidth = this.leftWidth
|
||||
const rightWidth = this.rightWidth
|
||||
if (this.deltaX === 0) {
|
||||
this.openState(false)
|
||||
return
|
||||
}
|
||||
if ((!open && rightWidth > 0 && -left > threshold) || (open && rightWidth > 0 && rightWidth + left <
|
||||
threshold)) {
|
||||
this.openState(true)
|
||||
} else {
|
||||
this.openState(false)
|
||||
}
|
||||
},
|
||||
openState(type) {
|
||||
const rightWidth = this.rightWidth
|
||||
let left = ''
|
||||
this.open = this.open ? this.open : false
|
||||
if (type) {
|
||||
left = -rightWidth
|
||||
} else {
|
||||
left = 0
|
||||
}
|
||||
if (this.open !== type) {
|
||||
this.$emit('change', {
|
||||
isOpen: type,
|
||||
param: this.param
|
||||
})
|
||||
}
|
||||
|
||||
this.open = type
|
||||
// 添加动画类
|
||||
this.ani = true
|
||||
this.$nextTick(() => {
|
||||
this.move(left)
|
||||
})
|
||||
},
|
||||
close() {
|
||||
this.openState(false)
|
||||
},
|
||||
getDirection(x, y) {
|
||||
if (x > y && x > MIN_DISTANCE) {
|
||||
return 'horizontal';
|
||||
}
|
||||
if (y > x && y > MIN_DISTANCE) {
|
||||
return 'vertical';
|
||||
}
|
||||
return '';
|
||||
},
|
||||
resetTouchStatus() {
|
||||
this.direction = '';
|
||||
this.deltaX = 0;
|
||||
this.deltaY = 0;
|
||||
this.offsetX = 0;
|
||||
this.offsetY = 0;
|
||||
},
|
||||
stopTouchStart(event) {
|
||||
this.resetTouchStatus();
|
||||
const touch = event.touches[0];
|
||||
this.startX = touch.clientX;
|
||||
this.startY = touch.clientY;
|
||||
},
|
||||
stopTouchMove(event) {
|
||||
const touch = event.touches[0];
|
||||
this.deltaX = touch.clientX - this.startX;
|
||||
this.deltaY = touch.clientY - this.startY;
|
||||
this.offsetX = Math.abs(this.deltaX);
|
||||
this.offsetY = Math.abs(this.deltaY);
|
||||
this.direction = this.direction || this.getDirection(this.offsetX, this.offsetY);
|
||||
},
|
||||
|
||||
getSelectorQuery() {
|
||||
uni.createSelectorQuery()
|
||||
// #ifndef MP-ALIPAY
|
||||
.in(this)
|
||||
// #endif
|
||||
.select('.' + this.elClass)
|
||||
.boundingClientRect(data => {
|
||||
if (data.length === 0) return
|
||||
this.rightWidth = data.width || 0
|
||||
this.isShow = this.show
|
||||
})
|
||||
.exec()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// #endif
|
||||
|
||||
// #ifdef APP-PLUS|| MP-WEIXIN || H5
|
||||
export default {}
|
||||
// #endif
|
107
components/firstui/fui-swipe-action/mpwxs.js
Normal file
107
components/firstui/fui-swipe-action/mpwxs.js
Normal file
@ -0,0 +1,107 @@
|
||||
// 本文件由FirstUI授权予新疆天衡创新研究院有限公司(手机号: 1861 4 0 72 549,身份证尾号:5A07X5)专用,请尊重知识产权,勿私下传播,违者追究法律责任。
|
||||
// #ifdef APP-VUE|| MP-WEIXIN || H5
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
isShow: false,
|
||||
isDisabled: false,
|
||||
thresholdVal: 30
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
show(newVal) {
|
||||
this.isShow = this.show
|
||||
},
|
||||
disabled(val) {
|
||||
this.isDisabled = this.disabled
|
||||
},
|
||||
threshold(val) {
|
||||
this.thresholdVal = Number(this.threshold)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.group = this.getParent()
|
||||
if (this.group.children !== undefined) {
|
||||
this.group.children.push(this)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
this.isShow = this.show
|
||||
this.isDisabled = this.disabled
|
||||
this.thresholdVal = Number(this.threshold)
|
||||
}, 10)
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
closeSwipe(e) {
|
||||
if (!this.autoClose) return
|
||||
this.group && this.group.closeAuto(this)
|
||||
},
|
||||
change(e) {
|
||||
this.$emit('change', {
|
||||
isOpen: e.open === 'right',
|
||||
param: this.param
|
||||
})
|
||||
if (this.isShow !== e.open) {
|
||||
this.isShow = e.open
|
||||
}
|
||||
},
|
||||
isPC() {
|
||||
var userAgentInfo = navigator.userAgent;
|
||||
var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
|
||||
var flag = true;
|
||||
for (let v = 0; v < Agents.length - 1; v++) {
|
||||
if (userAgentInfo.indexOf(Agents[v]) > 0) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return flag;
|
||||
},
|
||||
//解决 ios 13 点击区域错位的问题
|
||||
appTouchStart(e) {
|
||||
// #ifdef H5
|
||||
if (this.isPC()) return
|
||||
// #endif
|
||||
const {
|
||||
clientX
|
||||
} = e.changedTouches[0]
|
||||
this.clientX = clientX
|
||||
this.timestamp = new Date().getTime()
|
||||
},
|
||||
appTouchEnd(e, index, item) {
|
||||
// #ifdef H5
|
||||
if (this.isPC()) return
|
||||
// #endif
|
||||
const {
|
||||
clientX
|
||||
} = e.changedTouches[0]
|
||||
let diff = Math.abs(this.clientX - clientX)
|
||||
let time = (new Date().getTime()) - this.timestamp
|
||||
if (diff < 40 && time < 300) {
|
||||
this.$emit('click', {
|
||||
index,
|
||||
item,
|
||||
param: this.param
|
||||
})
|
||||
}
|
||||
},
|
||||
handleClick(index, item) {
|
||||
// #ifdef H5
|
||||
if (!this.isPC()) return
|
||||
this.$emit('click', {
|
||||
index,
|
||||
item,
|
||||
param: this.param
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// #endif
|
||||
// #ifndef APP-VUE|| MP-WEIXIN || H5
|
||||
export default {}
|
||||
// #endif
|
Reference in New Issue
Block a user