前言
1、代码段是一个Vue组件的模板、脚本和样式的完整实现。它结合element的一些组件(如el-select和el-radio-group),实现一个带有下拉选择、多选功能以及可选择"是/否"状态的组件。
2、组件实现一个复杂的选择和管理界面,用户可以从下拉列表中选择多个选项,选择后每个选项会在下方的radio-box中显示,并可以选择对应的"是/否"状态。通过handleCancel方法,用户可以移除某个选项,changeSelect方法则负责更新选项列表和状态。整个组件逻辑清晰,使用element提供的组件实现良好的用户交互体验。
效果图
template
代码
<template>
<div class="box">
<el-select
class="select"
v-model="formData.val"
multiple
collapse-tags
collapse-tags-tooltip
:max-collapse-tags="2"
placeholder="请选择"
@change="changeSelect"
>
<el-option
v-for="item in options"
:key="item.id"
:label="item.label"
:value="item.id"
/>
</el-select>
<div class="radio-box">
<div v-for="item in valList" :key="item.id">
<span @click="handleCancel(item)">{{ item.label }}</span>
<el-radio-group v-model="item.isType">
<el-radio :label="true">是</el-radio>
<el-radio :label="false">否</el-radio>
</el-radio-group>
</div>
</div>
</div>
</template>
解析
1、<el-select>
1.1、v-model
绑定formData.val,实现双向数据绑定。
1.2、multiple
属性允许多选。
1.3、collapse-tags
和collapse-tags-tooltip
配合使用,提供选择项的折叠展示,超出指定数量时显示提示。
1.4、max-collapse-tags="2"
设置最多折叠显示2个选项,其他选项折叠。
1.5、@change="changeSelect"
监听选择变化事件,调用changeSelect方法。
1.6、v-for="item in options"
遍历options数组,生成el-option子组件,item.id作为每个选项的唯一key,item.label作为显示的文本,item.id作为选项的值。
2、<div class="radio-box">
2.1、v-for="item in valList"
遍历valList数组,生成每个选项的名称和对应的单选框组。
2.2、@click="handleCancel(item)"
绑定点击事件,点击名称时会触发handleCancel方法,移除该选项。
2.3、el-radio-group
使用v-model
绑定item.isType,控制"是/否"状态。
2.4、el-radio
组件的label分别设置为true或false,对应"是"和"否"。
style
代码
.box {
margin: 0;
padding: 28px;
box-sizing: border-box;
> .select {
width: 100%;
}
.radio-box {
width: 100%;
> div {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
> span {
cursor: pointer;
}
}
}
}
解析
.box
1、包裹整个组件的容器。
2、设置padding: 28px;
确保内部元素有一定的间距。
3、box-sizing: border-box;
确保padding包含在元素宽度和高度内。
.select
1、将el-select设置为100%宽度,适应父容器。
.radio-box
1、包含所有单选框组的容器。
2、内部的每个div(对应valList中的一个选项)设置为flex布局,子元素(选项名称和单选框)水平排列。
3、> span
的cursor: pointer;
使光标在悬停时变为指针样式,提示用户该元素可点击。
JavaScript
代码
const runClone = val => JSON.parse(JSON.stringify(val));
export default {
name: 'demo',
data() {
return {
formData: {
val: []
},
options: [
{ id: 6, label: 'option-6', isType: true },
{ id: 2, label: 'option-2', isType: true },
{ id: 1, label: 'option-1', isType: true },
{ id: 4, label: 'option-4', isType: true },
{ id: 3, label: 'option-3', isType: true },
{ id: 5, label: 'option-5', isType: true },
{ id: 7, label: 'option-7', isType: true }
],
valList: [
{ id: 6, label: 'option-6', isType: false },
{ id: 3, label: 'option-3', isType: false },
{ id: 7, label: 'option-7', isType: true }
]
};
},
created() {
this.runInit();
},
methods: {
handleCancel(row = {}) {
let valList = runClone(this.valList);
let list = valList.filter(item => item.id !== row.id);
this.valList = list;
this.formData.val = list.map(item => item.id);
},
changeSelect(e) {
let options = runClone(this.options);
let valList = runClone(this.valList);
let list = [];
for (let i = 0; i < e.length; i++) {
let itemA = valList.filter(item => item.id === e[i])[0];
let itemB = options.filter(item => item.id === e[i])[0];
itemA ? list.push(itemA) : list.push(itemB);
}
list = list.sort((item1, item2) => {
const a = options.findIndex(item => item.id === item1.id);
const b = options.findIndex(item => item.id === item2.id);
return a - b;
});
this.valList = runClone(list);
},
runInit() {
this.formData.val = this.valList.map(item => item.id);
}
}
};
解析
runClone
方法使用JSON.parse(JSON.stringify(val))
深度克隆对象或数组。用于确保valList和options不被直接修改。
data()
1、formData.val
保存用户在el-select中选择的选项的id。
2、options
是可供选择的选项列表,每个选项有id、label和isType(表示"是/否"状态)。
3、valList
保存当前已选中的选项及其isType状态。初始值为option-6、option-3和option-7,分别对应不同的isType值。
created
生命周期钩子
1、调用runInit()方法,用于初始化formData.val。
handleCancel(row)
1、删除valList中与row.id匹配的选项。
2、更新formData.val使其同步。
changeSelect(e)
1、根据用户选择更新valList。
2、将新选择的选项按顺序添加到valList,并更新其中的isType值。
3、通过sort方法保持valList顺序与options顺序一致。
runInit()
1、初始化formData.val,确保它与valList中的选项一致。