在vue中把一个下拉框分成多个组并可以选择多个选项

通常一个字段如果有多个选择,我们会使用下拉框来表现数据,如支付类型(支付宝,微信,银行卡);但是有时候普通的下拉框满足不了业务需求,如我想选择多种支付方式,甚至如果支付方式又延伸为线上和线下两大类,线上为支付宝等等,线下为当面交易等等,这样页面的数据展示效果和页面与后台存值取值交互就变得更麻烦。但是vue已经为我们安排好了一切~

本篇博客就以上述场景作为例子来写一个demo。

效果图

在vue中把一个下拉框分成多个组并可以选择多个选项_第1张图片


建表以及初始数据SQL

-- 创建用户信息表
CREATE TABLE `user_info`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `user_name` varchar(255) NULL DEFAULT NULL COMMENT '用户名称',
  `remark` text NULL COMMENT '备注',
  `create_datetime` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`)
) COMMENT = '用户信息表';

-- 创建支付方式表
CREATE TABLE `pay_info`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `pay_name` varchar(255) NULL DEFAULT NULL COMMENT '支付方式名称',
  `parent_id` bigint(20) NULL DEFAULT NULL COMMENT '父级标签id',
  `remark` text NULL COMMENT '备注',
  `create_datetime` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`)
) COMMENT = '支付方式表';

-- 创建用户支付方式关联表
CREATE TABLE `user_pay_rel`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `user_id` bigint(20) NULL DEFAULT NULL COMMENT '用户id',
  `pay_info_id` bigint(20) NULL DEFAULT NULL COMMENT '支付方式id',
	`remark` text NULL COMMENT '备注',
  `create_datetime` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`)
) COMMENT = '用户支付方式关联表';


-- 插入初始数据
insert into user_info (user_name,remark) value ('斗苦故事','梦想成为全栈。');
insert into pay_info (pay_name,parent_id,remark) value ('线上',0,'线上支付方式(父)'),('支付宝',1,'线上支付方式(子)'),('微信',1,'线上支付方式(子)'),('网银支付',1,'线上支付方式(子)');
insert into pay_info (pay_name,parent_id,remark) value ('线下',0,'线下支付方式(父)'),('银行转账',5,'线下支付方式(子)'),('当面交易',5,'线下支付方式(子)');
insert into user_pay_rel (user_id,pay_info_id,remark) value (1,2,'使用支付宝支付'),(1,3,'使用微信支付'),(1,6,'到银行转账支付');

实体类 JavaBean

除了三张表各对应一个基础实体类外,还要额外创建三个扩展实体类

注:为了代码规范以及未来可扩展性,一般页面接收和返回的数据都会封装成一个扩展实体类

先分析一下下拉框多分组需要哪样的数据格式(对应上面的支付方式表的数据)

object : [

{

         parentLabelName:'线上',     ->     payName

         parentLabelValue:'1',           ->      id

         child: [       childLabelName -> payName ; childLabelValue -> id

                   {childLabelName:'支付宝',childLabelValue:'2'},

                   {childLabelName:'微信',childLabelValue:'3'},

                   {childLabelName:'网银支付',childLabelValue:'4'}

         ]

},

{

         parentLabelName:'线下',     ->     payName

         parentLabelValue:'5',           ->      id

         child: [       childLabelName -> payName ; childLabelValue -> id

                   {childLabelName:'银行转账',childLabelValue:'6'},

                   {childLabelName:'当面交易',childLabelValue:'7'}

         ]

},

]

  • object:第一个扩展对象,里面封装着父级对象
  • parentLabel:第二个扩展对象,里面封装着父级属性和子级对象
  • child:第三个扩展对象,里面封装着子级属性
  • 一共三层,最外面一层 object 就是返回到页面的主要对象,里面包含着父级集合(线上对象和线下对象),每一个父级对象中又包含一个子级集合(线上->支付宝/微信/网银支付   线下->银行转账/当面交易)

实体类 Java 代码

  • 三个基础实体类
    // UserInfo.java
    private static final long serialVersionUID = 1L;

    // 主键
    private Long id;
    // 用户名称
    private String userName;
    // 备注
    private String remark;
    // 创建时间
    private Date createDatetime;
    public Long getId() {return id;}
    public void setId(Long id) {this.id = id;}
    public String getUserName() {return userName;}
    public void setUserName(String userName) {this.userName = userName;}
    public String getRemark() {return remark;}
    public void setRemark(String remark) {this.remark = remark;}
    public Date getCreateDatetime() {return createDatetime;}
    public void setCreateDatetime(Date createDatetime) {this.createDatetime = createDatetime;}
    // PayInfo.java
    private static final long serialVersionUID = 1L;

    // 主键
    private Long id;
    // 支付方式名称
    private String payName;
    // 父级标签id
    private Long parentId;
    // 备注
    private String remark;
    // 创建时间
    private Date createDatetime;
    public Long getId() {return id;}
    public void setId(Long id) {this.id = id;}
    public String getPayName() {return payName;}
    public void setPayName(String payName) {this.payName = payName;}
    public Long getParentId() {return parentId;}
    public void setParentId(Long parentId) {this.parentId = parentId;}
    public String getRemark() {return remark;}
    public void setRemark(String remark) {this.remark = remark;}
    public Date getCreateDatetime() {return createDatetime;}
    public void setCreateDatetime(Date createDatetime) {this.createDatetime = createDatetime;}
    // UserPayRel.java
    private static final long serialVersionUID = 1L;

    // 主键
    private Long id;
    // 用户id
    private Long userId;
    // 支付方式id
    private Long payInfoId;
    // 备注
    private String remark;
    // 创建时间
    private Date createDatetime;
    public Long getId() {return id;}
    public void setId(Long id) {this.id = id;}
    public Long getUserId() {return userId;}
    public void setUserId(Long userId) {this.userId = userId;}
    public Long getPayInfoId() {return payInfoId;}
    public void setPayInfoId(Long payInfoId) {this.payInfoId = payInfoId;}
    public String getRemark() {return remark;}
    public void setRemark(String remark) {this.remark = remark;}
    public Date getCreateDatetime() {return createDatetime;}
    public void setCreateDatetime(Date createDatetime) {this.createDatetime = createDatetime;}
  • 第三个扩展对象,里面封装着子级属性
    // PayChildDTO.java
    private static final long serialVersionUID = 1L;

    // 主键
    private Long id;
    // 支付方式名称
    private String payName;
    // 父级标签id
    private Long parentId;
    // 备注
    private String remark;
    // 创建时间
    private Date createDatetime;
    public Long getId() {return id;}
    public void setId(Long id) {this.id = id;}
    public String getPayName() {return payName;}
    public void setPayName(String payName) {this.payName = payName;}
    public Long getParentId() {return parentId;}
    public void setParentId(Long parentId) {this.parentId = parentId;}
    public String getRemark() {return remark;}
    public void setRemark(String remark) {this.remark = remark;}
    public Date getCreateDatetime() {return createDatetime;}
    public void setCreateDatetime(Date createDatetime) {this.createDatetime = createDatetime;}
  • 第二个扩展对象,里面封装着父级属性和子级集合对象
    // PayParentDTO.java
    private static final long serialVersionUID = 1L;

    // 主键
    private Long id;
    // 支付方式名称
    private String payName;
    // 父级标签id
    private Long parentId;
    // 备注
    private String remark;
    // 创建时间
    private Date createDatetime;
    // 子级支付方式集合
    private List options;
    public Long getId() {return id;}
    public void setId(Long id) {this.id = id;}
    public String getPayName() {return payName;}
    public void setPayName(String payName) {this.payName = payName;}
    public Long getParentId() {return parentId;}
    public void setParentId(Long parentId) {this.parentId = parentId;}
    public String getRemark() {return remark;}
    public void setRemark(String remark) {this.remark = remark;}
    public Date getCreateDatetime() {return createDatetime;}
    public void setCreateDatetime(Date createDatetime) {this.createDatetime = createDatetime;}
    public List getOptions() {return options;}
    public void setOptions(List options) {this.options = options;}
  • 第一个扩展对象,里面封装着父级集合对象
    // PayResponseDTO.java
    private static final long serialVersionUID = 1L;

    // 父级支付方式集合
    private List options;
    public List getOptions() {return options;}
    public void setOptions(List options) {this.options = options;}

页面 vue 代码

payInfo.vue

  1.