老规矩----前面文章的步骤创建文件导入js等
1.cascader .vue 组件
<template>
<!--
cascaderData.value // 默认展示数据
options // 列表数据
radio // 是否单选 默认不是
multiple // 是否多选 默认不是
is-search // 是否远程搜索 默认不是
handleChange // 事件回调
<MjbCascader v-model="cascaderData.value" :options="cascaderData.options" :radio="false" @handleChange="handleChange"></MjbCascader> -->
<div>
<!-- 单选 -->
<el-cascader
v-if="radio"
v-model="cascaderData.valueArrRadio"
:options="options"
:props="cascaderData.propsObjRadio"
clearable
@change="handleChange"
>
<template #default="{ node, data }">
<span>{{ data[showName] }}</span>
<span v-if="!node.isLeaf"> ({{ data[childrenName].length }}) </span>
</template>
</el-cascader>
<!-- 多选 -->
<el-cascader
v-else-if="multiple"
v-model="cascaderData.valueArrMut"
:options="options"
:props="cascaderData.propsObj"
collapse-tags
collapse-tags-tooltip
clearable
@change="handleChange"
>
<template #default="{ node, data }">
<span>{{ data[showName] }}</span>
<span v-if="!node.isLeaf"> ({{ data[childrenName].length }}) </span>
</template>
</el-cascader>
<!-- 搜索 -->
<el-cascader
v-else-if="isSearch"
v-model="cascaderData.valueArrSearch"
:props="propsIsSearch"
clearable
@change="handleChange"
/>
<!-- 默认 -->
<el-cascader
v-else
v-model="cascaderData.valueDef"
:options="options"
:props="cascaderData.propsDef"
clearable
@change="handleChange"
>
<template #default="{ node, data }">
<span>{{ data[showName] }}</span>
<span v-if="!node.isLeaf"> ({{ data[childrenName].length }}) </span>
</template>
</el-cascader>
</div>
</template>
<script>
import { reactive, watch, ref } from 'vue'
const cascaderData = reactive({
propsObjRadio: { expandTrigger: 'hover' },
propsObj: { expandTrigger: 'hover' },
propsDef: { expandTrigger: 'hover' },
valueArrRadio: '',
valueArrMut: [],
valueArrSearch: [],
valueDef: []
})
export default {
props: {
// // 单选默认值
// valueAudio: {
// default() {
// return ''
// },
// type: String
// },
// // 多选默认值
title: {
default() {
return
},
// eslint-disable-next-line vue/require-prop-type-constructor
type: Number
},
// 数据的名称
showName: {
default() {
return 'label'
},
type: String
},
// children的名称
childrenName: {
default() {
return 'children'
},
type: String
},
// value的名称
valueName: {
default() {
return 'value'
},
type: String
},
radio: {
default() {
return false
},
type: Boolean
},
// 非搜索的数据
options: {
default() {
return []
},
type: Array
},
// 是否多选
multiple: {
default() {
return false
},
type: Boolean
},
// 是否是远程搜索状态
isSearch: {
default() {
return false
},
type: Boolean
},
// 搜索的数据
propsIsSearch: {
default() {
return {}
},
type: Object
}
},
emits: ['handleChange'],
setup(props, ctx) {
// 单选
if (props.radio) {
cascaderData.propsObjRadio = {
expandTrigger: 'hover',
checkStrictly: true,
children: props.childrenName,
label: props.showName,
value: props.valueName
}
}
// 多选
if (props.multiple) {
cascaderData.propsObj = {
expandTrigger: 'hover',
multiple: true,
children: props.childrenName,
label: props.showName,
value: props.valueName
}
}
// 搜索
if (props.isSearch) {
console.log(props.isSearch)
// console.log(cascaderData.propsObj)
} else {
// 默认
cascaderData.propsDef = {
expandTrigger: 'hover',
children: props.childrenName,
label: props.showName,
value: props.valueName
}
}
// eslint-disable-next-line vue/no-setup-props-destructure
watch(() => props.title, (n) => {
// 要执行的方法
// console.log(n)
if (props.radio) {
cascaderData.valueArrRadio = n
}
// 多选
if (props.multiple) {
cascaderData.valueArrMut.length = 0
cascaderData.valueArrMut.push(n)
} else {
cascaderData.valueDef.length = 0
cascaderData.valueDef.push(n)
}
}, { immediate: true, deep: true })
// console.log(props.options)
const handleChange = (value) => {
ctx.emit('handleChange', value)
}
return { cascaderData, handleChange }
}
}
</script>
2.使用
<template>
<div>
<span>默认Cascader</span>
<LZCascader
:show-name="cascaderData.showName"
:children-name="cascaderData.children"
:value-name="cascaderData.valuet"
:title="cascaderData.value"
:options="cascaderData.options"
:radio="false"
@handleChange="handleChange"
></LZCascader>
</div>
<div>
<span>单选Cascader</span>
<LZCascader
:show-name="cascaderData.showName"
:children-name="cascaderData.children"
:value-name="cascaderData.valuet"
:title="cascaderData.value2"
:options="cascaderData.options"
radio
@handleChange="handleChange2"
></LZCascader>
</div>
<div>
<span>多选Cascader</span>
<LZCascader
:show-name="cascaderData.showName"
:children-name="cascaderData.children"
:value-name="cascaderData.valuet"
:title="cascaderData.value3"
:options="cascaderData.options"
multiple
@handleChange="handleChange3"
></LZCascader>
</div>
<div>
<span>远程搜索Cascader</span>
<LZCascader
:show-name="cascaderData.showName"
:children-name="cascaderData.children"
:value-name="cascaderData.valuet"
:title="cascaderData.value4"
is-search
:props-is-search="cascaderData.propsIsSearch"
@handleChange="handleChange4"
></LZCascader>
</div>
</template>
<script>
import { reactive } from 'vue'
const cascaderData = reactive({
showName: 'label',
valuet: 'value',
children: 'children',
value: '',
value2: '',
value3: '',
value4: '',
propsIsSearch: {},
options: [
{
value: 'guide',
label: 'Guide',
disabled: true,
children: [
{
value: 'disciplines',
label: 'Disciplines',
children: [
{
value: 'consistency',
label: 'Consistency',
},
{
value: 'feedback',
label: 'Feedback',
},
{
value: 'efficiency',
label: 'Efficiency',
},
{
value: 'controllability',
label: 'Controllability',
},
],
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'side nav',
label: 'Side Navigation',
},
{
value: 'top nav',
label: 'Top Navigation',
},
],
},
],
},
{
value: 'component',
label: 'Component',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout',
},
{
value: 'color',
label: 'Color',
},
{
value: 'typography',
label: 'Typography',
},
{
value: 'icon',
label: 'Icon',
},
{
value: 'button',
label: 'Button',
},
],
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio',
},
{
value: 'checkbox',
label: 'Checkbox',
},
{
value: 'input',
label: 'Input',
},
{
value: 'input-number',
label: 'InputNumber',
},
{
value: 'select',
label: 'Select',
},
{
value: 'cascader',
label: 'Cascader',
},
{
value: 'switch',
label: 'Switch',
},
{
value: 'slider',
label: 'Slider',
},
{
value: 'time-picker',
label: 'TimePicker',
},
{
value: 'date-picker',
label: 'DatePicker',
},
{
value: 'datetime-picker',
label: 'DateTimePicker',
},
{
value: 'upload',
label: 'Upload',
},
{
value: 'rate',
label: 'Rate',
},
{
value: 'form',
label: 'Form',
},
],
},
{
value: 'data',
label: 'Data',
children: [
{
value: 'table',
label: 'Table',
},
{
value: 'tag',
label: 'Tag',
},
{
value: 'progress',
label: 'Progress',
},
{
value: 'tree',
label: 'Tree',
},
{
value: 'pagination',
label: 'Pagination',
},
{
value: 'badge',
label: 'Badge',
},
],
},
{
value: 'notice',
label: 'Notice',
children: [
{
value: 'alert',
label: 'Alert',
},
{
value: 'loading',
label: 'Loading',
},
{
value: 'message',
label: 'Message',
},
{
value: 'message-box',
label: 'MessageBox',
},
{
value: 'notification',
label: 'Notification',
},
],
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'menu',
label: 'Menu',
},
{
value: 'tabs',
label: 'Tabs',
},
{
value: 'breadcrumb',
label: 'Breadcrumb',
},
{
value: 'dropdown',
label: 'Dropdown',
},
{
value: 'steps',
label: 'Steps',
},
],
},
{
value: 'others',
label: 'Others',
children: [
{
value: 'dialog',
label: 'Dialog',
},
{
value: 'tooltip',
label: 'Tooltip',
},
{
value: 'popover',
label: 'Popover',
},
{
value: 'card',
label: 'Card',
},
{
value: 'carousel',
label: 'Carousel',
},
{
value: 'collapse',
label: 'Collapse',
},
],
},
],
},
{
value: 'resource',
label: 'Resource',
children: [
{
value: 'axure',
label: 'Axure Components',
},
{
value: 'sketch',
label: 'Sketch Templates',
},
{
value: 'docs',
label: 'Design Documentation',
},
],
},
]
})
export default {
setup() {
cascaderData.value = cascaderData.options[0].children[0].children[0].value
// 这里是远程搜索的逻辑
let id = 0
cascaderData.propsIsSearch = {
lazy: true,
multiple: true, // 是否多选
lazyLoad(node, resolve) {
const { level } = node
setTimeout(() => {
const nodes = Array.from({ length: level + 1 }).map((item) => ({
value: ++id,
label: `Option - ${id}`,
leaf: level >= 2
}))
// Invoke `resolve` callback to return the child nodes data and indicate the loading is finished.
resolve(nodes)
}, 1000)
}
}
const handleChange = (value) => {
console.log(value)
}
const handleChange2 = (value) => {
console.log(value)
}
const handleChange3 = (value) => {
console.log(value)
}
const handleChange4 = (value) => {
console.log(value)
}
return { cascaderData, handleChange, handleChange2, handleChange3, handleChange4 }
}
}
</script>