123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- 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()
- }
- },
- leftOptions() {
- this.getSelectorQuery()
- this.init()
- },
- rightOptions(newVal) {
- this.init()
- }
- },
- created() {
- if (this.swipeaction.children !== undefined) {
- this.swipeaction.children.push(this)
- }
- },
- mounted() {
- this.box = this.getEl(this.$refs['selector-box--hock'])
- this.selector = this.getEl(this.$refs['selector-content--hock']);
- this.leftButton = this.getEl(this.$refs['selector-left-button--hock']);
- this.rightButton = this.getEl(this.$refs['selector-right-button--hock']);
- this.init()
- },
- beforeDestroy() {
- this.swipeaction.children.forEach((item, index) => {
- if (item === this) {
- this.swipeaction.children.splice(index, 1)
- }
- })
- },
- methods: {
- init() {
- this.$nextTick(() => {
- this.x = 0
- this.button = {
- show: false
- }
- setTimeout(() => {
- this.getSelectorQuery()
- }, 200)
- })
- },
- onClick(index, item, position) {
- this.$emit('click', {
- content: item,
- index,
- position
- })
- },
- touchstart(e) {
- // 每次只触发一次,避免多次监听造成闪烁
- if (this.stop) return
- this.stop = true
- if (this.autoClose) {
- this.swipeaction.closeOther(this)
- }
-
- const leftWidth = this.button.left.width
- const rightWidth = this.button.right.width
- let expression = this.range(this.x, -rightWidth, leftWidth)
- let leftExpression = this.range(this.x - leftWidth, -leftWidth, 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.leftButton,
- property: 'transform.translateX',
- expression: leftExpression
- }, {
- element: this.rightButton,
- property: 'transform.translateX',
- expression: rightExpression
- }, ]
- }, (e) => {
- // nope
- if (e.state === 'end') {
- this.x = e.deltaX + this.x;
- this.isclick = true
- this.bindTiming(e.deltaX)
- }
- });
- },
- touchend(e) {
- if (this.isopen !== 'none' && !this.isclick) {
- this.open('none')
- }
- },
- bindTiming(x) {
- const left = this.x
- const leftWidth = this.button.left.width
- const rightWidth = this.button.right.width
- const threshold = this.threshold
- if (!this.isopen || this.isopen === 'none') {
- if (left > threshold) {
- this.open('left')
- } else if (left < -threshold) {
- this.open('right')
- } else {
- this.open('none')
- }
- } else {
- if ((x > -leftWidth && x < 0) || x > rightWidth) {
- if ((x > -threshold && x < 0) || (x - rightWidth > threshold)) {
- this.open('left')
- } else {
- this.open('none')
- }
- } else {
- if ((x < threshold && x > 0) || (x + leftWidth < -threshold)) {
- this.open('right')
- } else {
- this.open('none')
- }
- }
- }
- },
- /**
- * 移动范围
- * @param {Object} num
- * @param {Object} mix
- * @param {Object} max
- */
- range(num, mix, max) {
- return `min(max(x+${num}, ${mix}), ${max})`
- },
- /**
- * 开启swipe
- */
- open(type) {
- this.animation(type)
- },
- /**
- * 关闭swipe
- */
- close() {
- this.animation('none')
- },
- /**
- * 开启关闭动画
- * @param {Object} type
- */
- animation(type) {
- const time = 300
- const leftWidth = this.button.left.width
- const rightWidth = this.button.right.width
- if (this.eventpan && this.eventpan.token) {
- BindingX.unbind({
- token: this.eventpan.token,
- eventType: 'pan'
- })
- }
- switch (type) {
- case 'left':
- Promise.all([
- this.move(this.selector, leftWidth),
- this.move(this.leftButton, 0),
- this.move(this.rightButton, rightWidth * 2)
- ]).then(() => {
- this.setEmit(leftWidth, type)
- })
- break
- case 'right':
- Promise.all([
- this.move(this.selector, -rightWidth),
- this.move(this.leftButton, -leftWidth * 2),
- this.move(this.rightButton, 0)
- ]).then(() => {
- this.setEmit(-rightWidth, type)
- })
- break
- default:
- Promise.all([
- this.move(this.selector, 0),
- this.move(this.leftButton, -leftWidth),
- this.move(this.rightButton, rightWidth)
- ]).then(() => {
- this.setEmit(0, type)
- })
- }
- },
- setEmit(x, type) {
- const leftWidth = this.button.left.width
- const rightWidth = this.button.right.width
- this.isopen = this.isopen || 'none'
- this.stop = false
- this.isclick = false
- // 只有状态不一致才会返回结果
- if (this.isopen !== type && this.x !== x) {
- if (type === 'left' && leftWidth > 0) {
- this.$emit('change', 'left')
- }
- if (type === 'right' && rightWidth > 0) {
- this.$emit('change', 'right')
- }
- if (type === 'none') {
- this.$emit('change', 'none')
- }
- }
- 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)
- })
- })
- },
- /**
- * 获取ref
- * @param {Object} el
- */
- getEl(el) {
- return el.ref
- },
- /**
- * 获取节点信息
- */
- getSelectorQuery() {
- Promise.all([
- this.getDom('left'),
- this.getDom('right'),
- ]).then((data) => {
- let show = 'none'
- if (this.autoClose) {
- show = 'none'
- } else {
- show = this.show
- }
- if (show === 'none') {
- // this.close()
- } else {
- this.open(show)
- }
- })
- },
- getDom(str) {
- return new Promise((resolve, reject) => {
- dom.getComponentRect(this.$refs[`selector-${str}-button--hock`], (data) => {
- if (data) {
- this.button[str] = data.size
- resolve(data)
- } else {
- reject()
- }
- })
- })
- }
- }
- }
|