| | |
| | | let bindIngXMixins = {} |
| | | |
| | | // #ifdef APP-NVUE |
| | | const BindingX = uni.requireNativePlugin('bindingx'); |
| | | const dom = uni.requireNativePlugin('dom'); |
| | | const animation = uni.requireNativePlugin('animation'); |
| | | |
| | | bindIngXMixins = { |
| | | 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() { |
| | | this.swipeaction = this.getSwipeAction() |
| | | 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() |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | |
| | | // #endif |
| | | |
| | | export default bindIngXMixins |
| | | let bindIngXMixins = {}
|
| | |
|
| | | // #ifdef APP-NVUE
|
| | | const BindingX = uni.requireNativePlugin('bindingx');
|
| | | const dom = uni.requireNativePlugin('dom');
|
| | | const animation = uni.requireNativePlugin('animation');
|
| | |
|
| | | bindIngXMixins = {
|
| | | 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() {
|
| | | this.swipeaction = this.getSwipeAction()
|
| | | 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()
|
| | | }
|
| | | })
|
| | | })
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | // #endif
|
| | |
|
| | | export default bindIngXMixins
|