主要讲解 购买数量 选择 以及 有效时间选择 模块
数量增减 主要涉及到 最小最大范围 以及手动输入 只能输入数字的计算
有效时间选择 模块类radio 单选框 比较简单 监控当前选中的index
父组件
<div class="sales-board-line">
<div class="sales-board-line-left">
购买数量:
</div>
<div class="sales-board-line-right">
<v-counter @on-change="onParamChange('buyNum', $event)"></v-counter>
</div>
</div>
<div class="sales-board-line">
<div class="sales-board-line-left">
有效时间:
</div>
<div class="sales-board-line-right">
<v-chooser
:selections="periodList"
@on-change="onParamChange('period', $event)"></v-chooser>
</div>
</div>
<script>
import VCounter from '../../components/base/counter'
import VChooser from '../../components/base/chooser'
import _ from 'lodash'
export default {
components: {
VCounter,
VChooser
},
data () {
return {
buyNum: 0,
buyType: {},
versions: [],
period: {},
price: 0,
versionList: [
{
label: '客户版',
value: 0
},
{
label: '代理商版',
value: 1
},
{
label: '专家版',
value: 2
}
],
periodList: [
{
label: '半年',
value: 0
},
{
label: '一年',
value: 1
},
{
label: '三年',
value: 2
}
],
buyTypes: [
{
label: '入门版',
value: 0
},
{
label: '中级版',
value: 1
},
{
label: '高级版',
value: 2
}
],
isShowPayDialog: false,
bankId: null,
orderId: null,
isShowCheckOrder: false,
isShowErrDialog: false
}
},
methods: {
onParamChange (attr, val) {
this[attr] = val
// this.getPrice()
console.log(this[attr], attr)
},
getPrice () {
let buyVersionsArray = _.map(this.versions, (item) => {
return item.value
})
let reqParams = {
buyNumber: this.buyNum,
buyType: this.buyType.value,
period: this.period.value,
version: buyVersionsArray.join(',')
}
this.$http.post('/api/getPrice', reqParams)
.then((res) => {
this.price = res.data.amount
})
},
onChangeBanks (bankObj) {
this.bankId = bankObj.id
},
confirmBuy () {
let buyVersionsArray = _.map(this.versions, (item) => {
return item.value
})
let reqParams = {
buyNumber: this.buyNum,
buyType: this.buyType.value,
period: this.period.value,
version: buyVersionsArray.join(','),
bankId: this.bankId
}
this.$http.post('/api/createOrder', reqParams)
.then((res) => {
this.orderId = res.data.orderId
this.isShowCheckOrder = true
this.isShowPayDialog = false
}, (err) => {
this.isShowBuyDialog = false
this.isShowErrDialog = true
})
}
},
mounted () {
this.buyNum = 1
this.buyType = this.buyTypes[0]
this.versions = [this.versionList[0]]
this.period = this.periodList[0]
this.getPrice()
}
}
</script>
mounted 页面渲染完毕 加载默认选项 以及 调取数据接口
子组件
<template>
<div class="counter-component">
<div class="counter-btn" @click="minus"> - </div>
<div class="counter-show">
<input type="text" v-model="number" @keyup="fixNumber">
</div>
<div class="counter-btn" @click="add"> + </div>
</div>
</template>
<script>
export default {
props: {
max: {
type: Number,
default: 5
},
min: {
type: Number,
default: 1
}
},
data () {
return {
number: this.min
}
},
watch: {
number () {
this.$emit('on-change', this.number)
}
},
methods: {
fixNumber () {
let fix
if (typeof this.number === 'string') {
fix = Number(this.number.replace(/\D/g, ''))
}
else {
fix = this.number
}
if (fix > this.max || fix < this.min) {
fix = this.min
}
this.number = fix
},
minus () {
if (this.number <= this.min) {
return
}
this.number --
},
add () {
if (this.number >= this.max) {
return
}
this.number ++
}
}
}
</script>
<style scoped>
.counter-component {
position: relative;
display: inline-block;
overflow: hidden;
vertical-align: middle;
}
.counter-show {
float: left;
}
.counter-show input {
border: none;
border-top: 1px solid #e3e3e3;
border-bottom: 1px solid #e3e3e3;
height: 23px;
line-height: 23px;
width: 30px;
outline: none;
text-indent: 4px;
}
.counter-btn {
border: 1px solid #e3e3e3;
float: left;
height: 25px;
line-height: 25px;
width: 25px;
text-align: center;
cursor: pointer;
}
.counter-btn:hover {
border-color: #4fc08d;
background: #4fc08d;
color: #fff;
}
</style>
类radio单选框
子组件
<template>
<div class="chooser-component">
<ul class="chooser-list">
<li
v-for="(item, index) in selections"
@click="chosenSelection(index)"
:title="item.label"
:class="{active:index === nowIndex}"
>{{ item.label }}</li>
</ul>
</div>
</div>
</template>
<script>
export default {
props: {
selections: {
type: Array,
default: [{
label: 'test',
value: 0
}]
}
},
data () {
return {
nowIndex: 0
}
},
methods: {
chosenSelection (index) {
this.nowIndex = index
this.$emit('on-change', this.selections[index])
}
}
}
</script>
<style scoped>
.chooser-component {
position: relative;
display: inline-block;
}
.chooser-list li{
display: inline-block;
border: 1px solid #e3e3e3;
height: 25px;
line-height: 25px;
padding: 0 8px;
margin-right: 5px;
border-radius: 3px;
text-align: center;
cursor: pointer;
}
.chooser-list li.active {
border-color: #4fc08d;
background: #4fc08d;
color: #fff;
}
</style>