vuetify 学习第二天之v-combobox-自定义级联组件v-cascader封装
vuetify 学习第二天之v-combobox vuetify暂时未提供级联组件,我们可以结合element-ui或者iview等ui组件库的下拉部分,以及vuetify的v-combobox输入框部分,实现漂亮的自定义级联组件。 这里使用iview的cascader组件和vuetify的combobox组件。效果图:页面源代码:<...
vuetify学习第二天之v-combobox
目录
内容
0、简介
vuetify暂时未提供级联组件,我们可以结合element-ui或者iview等ui组件库的下拉部分,以及vuetify的v-combobox输入框部分,实现漂亮的自定义级联组件。
这里使用iview的cascader组件和vuetify的combobox组件。
- 效果图:
- 页面源代码:
<template>
<cas :data="options" @on-change="handleChange" :loadData="loadOption" transfer>
<v-combobox
:label="label"
chips
clearable
v-model="selected"
multiple
>
<template v-slot:selection="{ item }">
<v-chip
@click.stop
v-if="multiple"
close
@click:close="remove(item)"
small
outlined
color="green"
>{{ item.label }} </v-chip>
<v-chip @click.stop v-else small>{{ item.__label }}</v-chip>
</template>
</v-combobox>
</cas>
</template>
<script>
import { Cascader } from "iview";
export default {
name: "vCascader",
components: {
cas: Cascader
},
props: {
value: {},
label: {
type: String
},
url: {
type: String
},
itemText: {
type: String,
default: "name"
},
itemValue: {
type: String,
default: "id"
},
children: {
type: String,
default: "children"
},
multiple: {
type: Boolean,
default: false
},
showAllLevels: {
type: Boolean,
default: false
},
required: {
type: Boolean,
default: false
},
rules: {
type: Array
}
},
data() {
return {
options: [],
selected: [],
defaultRules: []
};
},
methods: {
handleChange(value, selectedData) {
console.log("start: ", this.selected);
// 获取最后一级
const option = selectedData[selectedData.length - 1];
// 如果是多选,则默认只保存最后一级选项
if (this.multiple) {
// 将最后一级保存到selected中
if (this.selected.findIndex(o => o.value === option.value) < 0) {
this.selected.push(option);
}
// 返回已选中的值
console.log("end: ", this.selected);
this.$emit("input", this.transfer(this.selected));
} else {
// 单选,则需要判断是否需要显示所有级别
if (this.showAllLevels) {
// 显示所有级别,将各级别label进行拼接
this.selected = [option.__label];
// 返回id数组
this.$emit("input", this.transfer(selectedData));
} else {
// 只显示最后一级
this.selected = [option.label];
// 返回
this.$emit("input", this.transfer([option])[0]);
}
}
},
loadOption(item, callback) {
// 延迟加载次级选项
item.loading = true;
this.loadData(item.value)
.then(data => {
item.children = data;
item.loading = false;
callback();
})
.catch(() => {
item.loading = false;
callback();
});
},
loadData(pid) {
// 从指定的url地址加载数据,并格式化
return new Promise(resolve => {
this.axios
.get(this.url, {
params: {
pid: pid
}
})
.then(resp => {
const data = [];
for (let d of resp.data) {
const node = {
value: d[this.itemValue],
label: d[this.itemText]
};
if (d.isParent) {
node["children"] = [];
node["loading"] = false;
}
data.push(node);
}
resolve(data);
});
});
},
remove(item) {
this.selected = this.selected.filter(o => o.value !== item.value);
this.$emit("input", this.transfer(this.selected));
},
transfer(arr) {
return arr.map(({ label, value }) => {
const obj = {};
obj[this.itemText] = label;
obj[this.itemValue] = value;
return obj;
});
},
validate() {
if (this.required) {
this.$refs.form.validate();
}
}
},
created() {
this.loadData(0).then(data => {
this.options = data;
});
if (this.required) {
this.defaultRules.push(v => v.length > 0 || this.label + "不能为空");
}
if (this.rules) {
this.rules.forEach(r => this.defaultRules.push(r));
}
},
watch: {
value: {
deep: true,
handler(val) {
if (!val) {
this.selected = [];
return;
}
if (val && this.showAllLevels && !this.multiple) {
this.selected = [val.map(o => o[this.itemText]).join("/")];
} else if (this.multiple && val) {
this.selected = val.map(o => {
return {
label: o[this.itemText],
value: o[this.itemValue]
};
});
} else {
this.selected = [val[this.itemText]];
}
}
}
}
};
</script>
<style scoped>
.ivu-cascader-menu-item {
font-size: 14px;
}
</style>
1、iview之cascader组件
- 官网地址:https://www.iviewui.com/components/cascader-en
- 缺点:选中展示为文字,很单调。
1.1、简介
级联选择框常用来从有明显分级结果的数据集和中选取数据,比如省/市/县,公司结构,商城分类等等。
1.2、常用属性
- 页面源代码:
<template>
<cas :data="options" @on-change="handleChange" :loadData="loadOption" transfer></cas>
<template>
<script>
...
data() {
return {
options: []
...
}
...
methods: {
handleChange(val, selectData){...} // 选择改变触发
loadOption(val){...} // 次级数据延迟加载
...
}
...
名称 | 默认值 | 描述 | 详解 |
---|---|---|---|
data | [] | 需要渲染的数据数组 | 1.2.1.1 |
value | [] | 选中的数据 | 1.2.1.2 |
load-data | - | 延迟加载函数 | 1.2.1.2 |
1.2.1、详细描述
1.2.1.1、data
- 示例:
常规形式:
data:[
{// 一级下拉框
text: '', // 每一项展示的内容
value: , // 每一项对应的key
children: [ // 二级下拉框
text: '',
value: ,
children: [...]
]
}
...
]
示例:
data: [
{
text: '手机',
value: 76,
children: [
{
text: '手机通讯',
value: 100,
children: [
text: '手机',
value: 260
]
}
]
}
...
]
- 详解
名称 | 类型 | 默认值 | 描述 |
---|---|---|---|
text | string | ‘’ | 每一项的显示的内容 |
value | key | 每一项的唯一标志 | |
children | array | [] | 子级下拉框数据 |
tips : value为每一项的唯一标志,建议用数据库返回的每一项的id值。
1.2.1.2、value
- 示例:
示例数据:
[76, 100, 260]
itips : value 中存储的为选择条目对应的vulue值的集合。
1.2.1.3 、load-data
- 示例:
// val 为点击条目对应的value值
loadData(val) {...} // load-data绑定的函数为延迟处理函数,用来延迟加载次级数据。触发时机:点击上级条目的时候触发。
1.3、常用事件
1.3.1、on-change
- 示例:
// onChange为on-change绑定的处理函数
onChange(val, selectedData){...}
- 参数详解
名称 | 类型 | 默认值 | 描述 |
---|---|---|---|
val | array | [] | 选中条目对应value值集合 |
selectedData | array | [] | 选中条目对应对象集合 |
tips :val与selectedData都为一维数组,只记录选中的条目。
2、vuetify之chip组件
2.1、简介
v-chip组件用来展示碎片化的信息,常被镶嵌于插槽中。
- 页面源代码:
<template v-slot:selection="{ item }">
<v-chip
@click.stop
v-if="multiple"
close
@click:close="remove(item)"
small
outlined
color="green"
>{{ item.label }} </v-chip>
<v-chip @click.stop v-else small>{{ item.__label }}</v-chip>
</template>
2.2、常用属性
名称 | 默认值 | 描述 | 详解 |
---|---|---|---|
close | false | 是否添加关闭图标 | |
color | undefined | 颜色 | 1.2.1.2 |
outlined | false | 是否显示幽灵样式 | 1.2.1.2 |
small | false | 是否大小变小 | 1.2.1.2 |
tips : v-chip组件相对很简单,不在做过多介绍,此处作为插槽内容嵌入cascader,用来替换原显示的文字,使cascader看起来更舒服。
2.3、常用事件
1.3.1、click:close
- 示例:
@click:close="remove(item)"
// remove为click:close绑定的处理函数,用来删除选中的某一项
remove(item){...}
- 参数详解
名称 | 类型 | 默认值 | 描述 |
---|---|---|---|
item | string/array | ‘’/[] | 要删除的项 |
tips :只有属性定义了close ,click:close才有意思,用来点击v-chip图标上小叉号,删除该项。
3、vuetify之combobox组件
- 官网地址:https://vuetifyjs.com/en/components/combobox
- 缺点:不能够实现级联选择,只能实现简单的下拉选择。
3.1、简介
v-combobox为带有自动完成功能,允许用户展示项目中不存在的值。
3.2、常用属性
- 页面源代码:
<v-combobox
:items="items"
:label="label"
chips
clearable
v-model="selected"
multiple
></v-combobox>
...
名称 | 默认值 | 描述 | 详解 |
---|---|---|---|
items | [] | 需要渲染的数据数组 | 3.2.1.1 |
value | ‘’/[] | 选中的数据 | 3.2.1.2 |
label ’‘ | 该下拉框提示标签 | 延迟加载函数 | 3.2.1.3 |
clearable | false | 是否可清除 | 3.2.1.4 |
chips | false | 是否展示为chip | 3.2.1.5 |
multiple | false | 是否可多选 | 3.2.1.6 |
3.2.1、详细描述
3.2.1.1、items
- 示例:
示例:
data: [
{
text: '手机',
value: 76,
},
{
text: '电脑',
value: 100
}
...
]
- 详解
名称 | 类型 | 默认值 | 描述 |
---|---|---|---|
text | string/number/object | 每一项的显示的内容 | |
value | string/number/object | 每一项的唯一标志 |
tips :v-combobox作为下拉框,显示内容比较简单。
3.2.1.2、value与iview组件类似
- 示例:
示例数据:
[76, 100, 260]
或者
67
itips : value是单相数值还是数组有 multiple决定,数据类型由items中数据决定。multiple为true,value为数组;multiple为false,value值为单值。
3.2.1.3 、label
- 作用同input的label
3.2.1.4、clearable
- 是否可清楚,既input框后带X号标记,点击可一次清空input框。
3.2.1.5、multipl 多选
3.3、常用事件与插槽
- 参考官网和iview,这里不在详述。
4、自定义v-cascader组件
因为iview下拉框和vuetify下拉框各自有缺点和优点,刚好实现互补,这里就结合2者自定义实现本文开始展示的级联插件。
4.1、简单解析
- iview部分为下拉框部分结构、样式和行为,vuetify为输入框部分结构、样式和行为
- 桥梁: 通过监听i-cascader的value值的变化,改变v-conbobox的value的变化,实现整体的下拉框选择和输入框展示更新。
- 渲染数据为请求后,稍加修改为符合展示的数据
- v-combobox 允许展示渲染数据没有的项
- data中props数组为自定义属性名称、类型及默认值,详细参考vue自定义组件。
后记: 刚开始学习vuetify ui组件,如有错误之处欢迎指正,共同进步,本人QQ:806797785
更多推荐
所有评论(0)