vue实现三级联动,多级联动

20 篇文章 0 订阅
6 篇文章 1 订阅

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部分:

<!-- vue挂载的元素上设置v-cloak属性,并在css里设置[v-cloak] {display: none;} 来防止页面加载时闪烁出现vue标签或者指令的问题-->
<div id="app" v-cloak>
    <ul class="select-options">
        <li>
        	<!-- 选取品牌时,将产品类型,产品名称,内存,颜色,IMEI等置空,为null -->
        	<!-- 下面分别选择产品类型,名称,内存,颜色时同理,需要将相应的值置空 -->
            <label>选择品牌</label>
            <select v-model='brand' @change="type=null,name=null,ram=null, color=null, imei=null">
                <option disabled="disabled" :value="null">请选择</option>
                <option v-for='(item, index) in product' :value="index">{{item.brand}}</option>
            </select>
        </li>
        <li>
            <label>产品类型</label>
            <select v-model='type' @change="name=null,ram=null, color=null, imei=null">
                <option disabled="disabled" :value="null">请选择</option>
                <option v-for='(item, index) in typeArray' :value="index">{{item.type}}</option>
            </select>
        </li>
        <li>
            <label>产品名称</label>
            <select v-model='name' @change="ram=null, color=null, imei=null">
                <option disabled="disabled" :value="null">请选择</option>
                <option v-for='(item, index) in nameArray' :value="index">{{item.name}}</option>
            </select>
        </li>
        <li>
            <label><span><i>内</i><i>存</i></span></label>
            <select v-model='ram' @change="color=null, imei=null">
                <option disabled="disabled" :value="null">请选择</option>
                <option v-for='(item, index) in ramArray' :value="index">{{item.ram}}</option>
            </select>
        </li>
        <li>
            <label><span><i>颜</i><i>色</i></span></label>
            <select v-model='color' @change="imei=null">
                <option disabled="disabled" :value="null">请选择</option>
                <option v-for='(item, index) in colorArray' :value="index">{{item}}</option>
            </select>
        </li>
        <li v-show="imeiShow">
            <label @click="showImeiTip">IMEI码</label>
            <input type="text" v-model="imei">
            <img src="./img/3c_camera.png" @click="useCamera" alt="">
        </li>
    </ul>
    <div class="btn" @click="submit()">提交信息</div>

</div>

多级联动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
                }
            }
        }
    })

点击这里尝试运行效果!

  • 13
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
您可以使用 Cascader 组件来实现 ant-design-vue三级联动。Cascader 组件是一个级联选择器,可以方便地实现级联选择。您可以在 Cascader 组件中设置 options 属性来定义选项列表,然后在 onChange 事件中获取选中的值。以下是一个示例代码: ``` <template> <a-cascader :options="options" v-model="selectedValues" @change="handleChange"></a-cascader> </template> <script> export default { data() { return { options: [ { value: 'beijing', label: '北京', children: [ { value: 'dongcheng', label: '东城', children: [ { value: 'tiananmen', label: '天安门' }, { value: 'wangfujing', label: '王府井' } ] }, { value: 'xicheng', label: '西城', children: [ { value: 'xidan', label: '西单' }, { value: 'fuchengmen', label: '阜成门' } ] } ] }, { value: 'shanghai', label: '上海', children: [ { value: 'pudong', label: '浦东', children: [ { value: 'lujiazui', label: '陆家嘴' }, { value: 'zhangjiang', label: '张江' } ] }, { value: 'puxi', label: '浦西', children: [ { value: 'nanjinglu', label: '南京路' }, { value: 'thebund', label: '外滩' } ] } ] } ], selectedValues: [] } }, methods: { handleChange(value) { console.log(value) } } } </script> ``` 在这个示例中,我们定义了一个 options 数组,其中包含了北京和上海两个城市,每个城市下面又包含了两个区域,每个区域下面又包含了两个街道。当用户选择某个选项时,会触发 onChange 事件,我们可以在事件处理函数中获取到用户选择的值。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值