|
@@ -1,6 +1,9 @@
|
|
<template>
|
|
<template>
|
|
<div class="buy-submit-sticky sticky-footer">
|
|
<div class="buy-submit-sticky sticky-footer">
|
|
- <div class="flex-r-c v-w1200">
|
|
|
|
|
|
+ <div class="sticky-footer-tip-container">
|
|
|
|
+ <slot name="sticky-footer-tip"></slot>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="sticky-content flex-r-c v-w1200">
|
|
<div class="price-agreement">
|
|
<div class="price-agreement">
|
|
<el-checkbox :value="agreement" @change="agreeCheckboxChange">
|
|
<el-checkbox :value="agreement" @change="agreeCheckboxChange">
|
|
<span>已阅读并同意</span>
|
|
<span>已阅读并同意</span>
|
|
@@ -28,23 +31,28 @@
|
|
</slot>
|
|
</slot>
|
|
</div>
|
|
</div>
|
|
<div class="price-submit-container">
|
|
<div class="price-submit-container">
|
|
- <button class="price-submit" :disabled="confirmButtonDisabled" @click="buySubmit">
|
|
|
|
- <div class="confirm-button-text">确定支付</div>
|
|
|
|
- <div class="confirm-button-tip-text" v-if="submitTipText">{{submitTipText}}</div>
|
|
|
|
- </button>
|
|
|
|
|
|
+ <el-button plain class="submit-button preview-button" @click="onCancel" v-show="plainButtonText">{{ plainButtonText }}</el-button>
|
|
|
|
+ <el-button type="primary" class="submit-button price-submit" :disabled="confirmButtonDisabled" :loading="loading" @click="buySubmit">
|
|
|
|
+ <div class="button-content">
|
|
|
|
+ <div class="confirm-button-text">{{submitText}}</div>
|
|
|
|
+ <div class="confirm-button-tip-text" v-if="submitTipText">{{submitTipText}}</div>
|
|
|
|
+ </div>
|
|
|
|
+ </el-button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<script>
|
|
<script>
|
|
-import { Checkbox, Link } from 'element-ui'
|
|
|
|
|
|
+import { Checkbox, Link, Button } from 'element-ui'
|
|
|
|
+import { debounce, throttle } from 'lodash'
|
|
|
|
|
|
export default {
|
|
export default {
|
|
name: 'buy-submit-sticky',
|
|
name: 'buy-submit-sticky',
|
|
components: {
|
|
components: {
|
|
[Checkbox.name]: Checkbox,
|
|
[Checkbox.name]: Checkbox,
|
|
- [Link.name]: Link
|
|
|
|
|
|
+ [Link.name]: Link,
|
|
|
|
+ [Button.name]: Button
|
|
},
|
|
},
|
|
model: {
|
|
model: {
|
|
prop: 'agreement',
|
|
prop: 'agreement',
|
|
@@ -59,6 +67,22 @@ export default {
|
|
type: Boolean,
|
|
type: Boolean,
|
|
default: false
|
|
default: false
|
|
},
|
|
},
|
|
|
|
+ plainButtonText: {
|
|
|
|
+ type: String,
|
|
|
|
+ default: ''
|
|
|
|
+ },
|
|
|
|
+ submitText: {
|
|
|
|
+ type: String,
|
|
|
|
+ default: '确定支付'
|
|
|
|
+ },
|
|
|
|
+ submitTipText: {
|
|
|
|
+ type: String,
|
|
|
|
+ default: ''
|
|
|
|
+ },
|
|
|
|
+ loading: {
|
|
|
|
+ type: Boolean,
|
|
|
|
+ default: false
|
|
|
|
+ },
|
|
containerSelector: {
|
|
containerSelector: {
|
|
type: String,
|
|
type: String,
|
|
default: '#recharge'
|
|
default: '#recharge'
|
|
@@ -81,10 +105,6 @@ export default {
|
|
type: Boolean,
|
|
type: Boolean,
|
|
default: true
|
|
default: true
|
|
},
|
|
},
|
|
- submitTipText: {
|
|
|
|
- type: String,
|
|
|
|
- default: ''
|
|
|
|
- },
|
|
|
|
linkUnderline: {
|
|
linkUnderline: {
|
|
type: Boolean,
|
|
type: Boolean,
|
|
default: false
|
|
default: false
|
|
@@ -92,25 +112,37 @@ export default {
|
|
},
|
|
},
|
|
mounted () {
|
|
mounted () {
|
|
this.windowScrollFn()
|
|
this.windowScrollFn()
|
|
|
|
+ this.calcStickyFooterMaxWitch()
|
|
this.$on('hook:mounted', () => {
|
|
this.$on('hook:mounted', () => {
|
|
// dom插入到根元素
|
|
// dom插入到根元素
|
|
this.appendDomToContainer(this.$el, this.containerSelector)
|
|
this.appendDomToContainer(this.$el, this.containerSelector)
|
|
- $(window).on('scroll', this.windowScrollFn)
|
|
|
|
- $('body').on('scroll', this.windowScrollFn)
|
|
|
|
- $(window).on('resize', this.windowScrollFn)
|
|
|
|
|
|
+ window.addEventListener('scroll', this.windowScrollFn)
|
|
|
|
+ window.addEventListener('resize', this.windowScrollFn)
|
|
|
|
+ window.addEventListener('resize', this.calcStickyFooterMaxWitch)
|
|
})
|
|
})
|
|
this.$on('hook:destroyed', () => {
|
|
this.$on('hook:destroyed', () => {
|
|
this.removeDomFromContainer(this.$el, this.containerSelector)
|
|
this.removeDomFromContainer(this.$el, this.containerSelector)
|
|
- $(window).off('scroll', this.windowScrollFn)
|
|
|
|
- $('body').off('scroll', this.windowScrollFn)
|
|
|
|
- $(window).off('resize', this.windowScrollFn)
|
|
|
|
|
|
+ window.removeEventListener('scroll', this.windowScrollFn)
|
|
|
|
+ window.removeEventListener('resize', this.windowScrollFn)
|
|
|
|
+ window.removeEventListener('resize', this.calcStickyFooterMaxWitch)
|
|
})
|
|
})
|
|
},
|
|
},
|
|
methods: {
|
|
methods: {
|
|
|
|
+ calcStickyFooterMaxWitch: debounce(function () {
|
|
|
|
+ const $el = this.$el
|
|
|
|
+ const $parent = this.$el.parentNode
|
|
|
|
+ if ($parent) {
|
|
|
|
+ let maxWidth = $parent.clientWidth
|
|
|
|
+ if (maxWidth) {
|
|
|
|
+ maxWidth = maxWidth <= 1200 ? 1200 : maxWidth
|
|
|
|
+ $el.style.maxWidth = `${maxWidth}px`
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }, 50),
|
|
appendDomToContainer (el, selector) {
|
|
appendDomToContainer (el, selector) {
|
|
var container
|
|
var container
|
|
if (selector) {
|
|
if (selector) {
|
|
- container = document.querySelector(selector)
|
|
|
|
|
|
+ container = this.$root.$el.querySelector(selector) || this.$root.$el
|
|
}
|
|
}
|
|
if (!container) {
|
|
if (!container) {
|
|
container = document.body
|
|
container = document.body
|
|
@@ -120,7 +152,7 @@ export default {
|
|
removeDomFromContainer (el, selector) {
|
|
removeDomFromContainer (el, selector) {
|
|
var container
|
|
var container
|
|
if (selector) {
|
|
if (selector) {
|
|
- container = document.querySelector(selector)
|
|
|
|
|
|
+ container = this.$root.$el.querySelector(selector)
|
|
}
|
|
}
|
|
if (!container) {
|
|
if (!container) {
|
|
container = document.body
|
|
container = document.body
|
|
@@ -164,25 +196,25 @@ export default {
|
|
const inViewport = offsetTop <= window.innerHeight && offsetBottom >= x
|
|
const inViewport = offsetTop <= window.innerHeight && offsetBottom >= x
|
|
return inViewport
|
|
return inViewport
|
|
},
|
|
},
|
|
- windowScrollFn () {
|
|
|
|
|
|
+ windowScrollFn: throttle(function () {
|
|
// 购买底部固定
|
|
// 购买底部固定
|
|
// 判断xx是否处于可视区域
|
|
// 判断xx是否处于可视区域
|
|
|
|
+ const $ = this.$querySelector.bind(this)
|
|
const mainFooter = $(this.basicSelector)
|
|
const mainFooter = $(this.basicSelector)
|
|
const stickyFooter = $(this.$el)
|
|
const stickyFooter = $(this.$el)
|
|
|
|
|
|
if (!mainFooter.length) return
|
|
if (!mainFooter.length) return
|
|
|
|
|
|
const show = !this.isInViewport(mainFooter[0])
|
|
const show = !this.isInViewport(mainFooter[0])
|
|
-
|
|
|
|
if (show) {
|
|
if (show) {
|
|
stickyFooter.show()
|
|
stickyFooter.show()
|
|
|
|
|
|
// 吸底
|
|
// 吸底
|
|
// 如果距离底部
|
|
// 如果距离底部
|
|
- const bottomFooter = $('.j-bottom')
|
|
|
|
|
|
+ const bottomFooter = document.querySelector('.j-bottom')
|
|
let ob = { top: 0 }
|
|
let ob = { top: 0 }
|
|
- if (bottomFooter.length) {
|
|
|
|
- ob = bottomFooter[0] && bottomFooter[0].getBoundingClientRect()
|
|
|
|
|
|
+ if (bottomFooter) {
|
|
|
|
+ ob = bottomFooter.getBoundingClientRect()
|
|
}
|
|
}
|
|
// bottom出现在视口
|
|
// bottom出现在视口
|
|
const bottom = window.innerHeight - ob.top
|
|
const bottom = window.innerHeight - ob.top
|
|
@@ -194,10 +226,13 @@ export default {
|
|
} else {
|
|
} else {
|
|
stickyFooter.hide()
|
|
stickyFooter.hide()
|
|
}
|
|
}
|
|
- },
|
|
|
|
|
|
+ }, 300),
|
|
agreeCheckboxChange (f) {
|
|
agreeCheckboxChange (f) {
|
|
this.$emit('change', f)
|
|
this.$emit('change', f)
|
|
},
|
|
},
|
|
|
|
+ onCancel () {
|
|
|
|
+ this.$emit('cancel')
|
|
|
|
+ },
|
|
buySubmit () {
|
|
buySubmit () {
|
|
this.$emit('submit')
|
|
this.$emit('submit')
|
|
}
|
|
}
|
|
@@ -208,13 +243,6 @@ export default {
|
|
<style lang="scss" scoped>
|
|
<style lang="scss" scoped>
|
|
$color_main: #2CB7CA;
|
|
$color_main: #2CB7CA;
|
|
|
|
|
|
-.confirm-button-tip-text {
|
|
|
|
- margin-top: 2px;
|
|
|
|
- font-size: 12px;
|
|
|
|
- line-height: 18px;
|
|
|
|
- color: rgba(255, 255, 255, 0.65);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
.sticky-footer {
|
|
.sticky-footer {
|
|
position: fixed;
|
|
position: fixed;
|
|
bottom: 0;
|
|
bottom: 0;
|
|
@@ -222,9 +250,21 @@ $color_main: #2CB7CA;
|
|
width: 100%;
|
|
width: 100%;
|
|
background-color: #fff;
|
|
background-color: #fff;
|
|
box-shadow: 0px -4px 8px 1px rgba(0, 0, 0, 0.05);
|
|
box-shadow: 0px -4px 8px 1px rgba(0, 0, 0, 0.05);
|
|
|
|
+ transition: max-width,width 0.5s ease;
|
|
|
|
+}
|
|
|
|
+.confirm-button-tip-text {
|
|
|
|
+ margin-top: 2px;
|
|
|
|
+ font-size: 12px;
|
|
|
|
+ line-height: 18px;
|
|
|
|
+ color: rgba(255, 255, 255, 0.65);
|
|
}
|
|
}
|
|
.buy-submit-sticky {
|
|
.buy-submit-sticky {
|
|
- padding: 12px 0;
|
|
|
|
|
|
+ > .v-w1200 {
|
|
|
|
+ max-width: 1200px;
|
|
|
|
+ }
|
|
|
|
+ .sticky-content {
|
|
|
|
+ padding: 12px 0;
|
|
|
|
+ }
|
|
.price-preview {
|
|
.price-preview {
|
|
flex: 1;
|
|
flex: 1;
|
|
justify-content: flex-end;
|
|
justify-content: flex-end;
|
|
@@ -281,13 +321,16 @@ $color_main: #2CB7CA;
|
|
display: flex;
|
|
display: flex;
|
|
align-items: center;
|
|
align-items: center;
|
|
justify-content: flex-end;
|
|
justify-content: flex-end;
|
|
- .price-submit {
|
|
|
|
|
|
+ .submit-button {
|
|
display: flex;
|
|
display: flex;
|
|
align-items: center;
|
|
align-items: center;
|
|
justify-content: center;
|
|
justify-content: center;
|
|
- flex-direction: column;
|
|
|
|
- width: 180px;
|
|
|
|
|
|
+ padding-top: 0;
|
|
|
|
+ padding-bottom: 0;
|
|
height: 46px;
|
|
height: 46px;
|
|
|
|
+ }
|
|
|
|
+ .price-submit {
|
|
|
|
+ width: 180px;
|
|
line-height: 1;
|
|
line-height: 1;
|
|
text-align: center;
|
|
text-align: center;
|
|
font-size: 16px;
|
|
font-size: 16px;
|
|
@@ -299,6 +342,13 @@ $color_main: #2CB7CA;
|
|
opacity: 0.5;
|
|
opacity: 0.5;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ .button-content {
|
|
|
|
+ margin-left: 8px;
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ justify-content: center;
|
|
|
|
+ flex-direction: column;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|