vue做项目的时候,遇到了要实现多级联动的需求,由于只是小功能,就没有引入插件,自己实现了一下。
需求: 需要统计用户购买的3C产品的信息,如下图
需求评审的时候确定了让前端存储维护产品信息,所以下面代码中会保存着这些信息,而不是以通过请求后端接口的形式获得。
数据大概是这样的结构:
var product = [
{
brand: 'Apple',
type: [
{
type: 'iPhone',
name: [
{
name: 'iPhone XS',
ram: [
{
ram: '64G',
color: ['金色', '白色', '绿色']
},
{
ram: '128G',
color: ['金色', '白色', '绿色']
}
]
},
{
name: 'iPhone XS MAX',
ram: [
{
ram: '64G',
color: ['金色', '白色', '绿色']
},
{
ram: '128G',
color: ['金色', '白色', '绿色']
}
]
}
]
},
{
type: 'iPad',
name: [
{
name: 'IPad Air 无线局域网机型',
ram: [
{
ram: '64G',
color: ['金色', '白色', '绿色']
},
{
ram: '128G',
color: ['金色', '白色', '绿色']
}
]
},
{
name: 'Ipad Air 无线局域网 + 蜂窝网络机型',
ram: [
{
ram: '64G',
color: ['金色', '白色', '绿色']
},
{
ram: '128G',
color: ['金色', '白色', '绿色']
}
]
}
]
}
]
}
]
多级联动部分主要html部分:
提交信息
多级联动JS部分:
var app = new Vue({
el: '#app',
data: {
imei: '',
imeiMaskShow: false,
cameraShow: false,
brand: null,
type: null,
name: null,
ram: null,
color: null,
error: null,
submitFlag: true,
product: product
},
created: function () {
},
computed: {
//获得品类信息
typeArray: function () {
return this.brand !== null ? this.product[this.brand].type : null
},
//获得所选取产品名称信息
nameArray: function () {
return (this.type !== null && this.typeArray.length) ? this.typeArray[this.type].name : null
},
//获得所所选产品内存信息
ramArray: function () {
return (this.name !== null && this.nameArray.length) ? this.nameArray[this.name].ram : null
},
//获得所选产品颜色信息
colorArray: function () {
return (this.ram !== null && this.ramArray.length) ? this.ramArray[this.ram].color : null
},
//获得所选产品IMEI信息
//当所选产品类型是iPhone时,显示IMEI选项
imeiShow: function () {
return this.brand === 0 && this.type === 0 ? true : false
},
//提交前的完整性验证
check: function () {
this.error = null;
switch (true) {
case this.brand === null:
this.error = '品牌'
break;
case this.type === null:
this.error = '产品类型'
break;
case this.name === null:
this.error = '产品名称'
break;
case this.ram === null:
this.error = '内存'
break;
case this.color === null:
this.error = '颜色'
break;
case this.imeiShow && !this.imei:
this.error = 'IMEI'
break;
}
return this.error
}
},
methods: {
showImeiTip: function () {
this.imeiMaskShow = true
},
closeImeiTip: function () {
this.imeiMaskShow = false
},
cancleCamera: function () {
this.cameraShow = false;
},
useCamera: function () {
this.cameraShow = true
},
//合并对象
mergeObj: function (target, source) {
for (var obj in source) {
target[obj] = source[obj];
}
return target;
},
//提交信息
submit: function (cb) {
if (this.check) {
alert('请填写' + this.error + '信息')
return false;
}
var data = {
"brand": this.product[this.brand].brand,
"type": this.typeArray[this.type].type,
"name": this.nameArray[this.name].name,
"memory": this.ramArray[this.ram].ram,
"color": this.colorArray[this.color],
}
//如果有IMEI信息,则提交时应该将该信息一并提交
data = this.imei ? this.mergeObj(data, {'IMEI': this.imei}) : data;
var that = this
//防重复提交
if(that.submitFlag) {
that.submitFlag = false
$.ajax({
url: path + '/abc/check',
type: 'post',
//后端要求传这样的数据格式
data: {'info': JSON.stringify(data)},
success: function (res) {
//提交成功的回调函数
cb && cb()
that.submitFlag = true
},
error: function (error) {
that.submitFlag = true
alert('请求失败')
}
})
that.submitFlag = false
}
}
}
})