123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384 |
- import { NPopover, NScrollbar } from 'naive-ui';
- import {
- PropType,
- computed,
- defineComponent,
- onMounted,
- reactive,
- ref,
- toRefs,
- watch
- } from 'vue';
- import styles from './index.module.less';
- import arrowDown from './images/icon-arrow-down.png';
- import arrowUp from './images/icon-arrow-up.png';
- export default defineComponent({
- name: 'c-cascader',
- props: {
- value: {
- type: String,
- default: ''
- },
- options: {
- type: Array as PropType<any[]>,
- default: () => []
- },
- placeholder: {
- type: String,
- default: '请选择'
- },
- placement: {
- type: String,
- default: 'bottom-start'
- }
- },
- emits: ['update:value'],
- setup(props, { emit }) {
- const state = reactive({
- popoverShow: false,
- selectParents: {}, // 选中的数据
- tagActiveId: '' as any,
- tagActive: {} as any,
- childSelectId: null as any
- });
- // const formatParentCurrentValue = (ids: any, list: any) => {
- // for (const item of list) {
- // if (ids.includes(item.id)) {
- // if (item.children && item.children.length > 0) {
- // let lastId: any;
- // item.children.forEach((child: any) => {
- // if (ids.includes(child.id)) {
- // lastId = child.id;
- // }
- // });
- // item.activeIndex = lastId;
- // }
- // }
- // if (item.children && item.children.length > 0) {
- // formatParentCurrentValue(ids, item.children);
- // }
- // }
- // };
- const initParentSelect = (subject: any) => {
- let children: any;
- let columnName = '';
- if (subject.children) {
- children = [
- {
- columnName: subject.children[0].columnName,
- name: '全部' + subject.children[0].columnName || '',
- id: ''
- },
- ...subject.children
- ];
- columnName = subject.children[0].columnName;
- state.selectParents = {
- ...subject,
- columnName,
- activeIndex: '',
- children
- };
- } else {
- state.selectParents = {};
- }
- };
- // watch(
- // () => state.popoverShow,
- // () => {
- // if (!state.popoverShow || !props.value) return;
- // let ids = formatParentId(props.value, props.options);
- // state.tagActiveId = ids[0].id;
- // props.options.forEach((item: any) => {
- // if (item.id === state.tagActiveId) {
- // initParentSelect(item);
- // }
- // });
- // //
- // const index = ids.findIndex((child: any) => child.id === props.value);
- // ids = ids.slice(0, index + 1);
- // const values = ids.map((item: any) => {
- // return item.id;
- // });
- // console.log(values, 'values');
- // formatParentCurrentValue(values, props.options);
- // }
- // );
- const valueText = computed(() => {
- const id = props.value;
- const values = getValues(id);
- const names: any = [];
- values.forEach((item: any) => {
- names.push(item.name);
- });
- return names.join(' / ');
- });
- // 递归获取数据
- const formatParentId = (id: any, list: any, ids = [] as any) => {
- for (const item of list) {
- if (item.children && item.children.length > 0) {
- const cIds: any = formatParentId(id, item.children, [
- ...ids,
- {
- name: item.name,
- id: item.id
- }
- ]);
- const index = cIds.findIndex((c: any) => c.id === id);
- if (index > -1) {
- return cIds;
- }
- }
- if (item.id === id) {
- return [
- ...ids,
- {
- name: item.name,
- id
- }
- ];
- }
- }
- return ids;
- };
- const getValues = (value: any) => {
- let ids = formatParentId(value, props.options);
- const index = ids.findIndex((child: any) => child.id === value);
- ids = ids.slice(0, index + 1);
- return ids;
- };
- // 重置
- const onReset = () => {
- state.childSelectId = null;
- state.tagActiveId = '';
- state.selectParents = {};
- emit('update:value', '');
- state.popoverShow = false;
- };
- // 提交
- const onConfirm = () => {
- emit('update:value', state.childSelectId || state.tagActiveId);
- state.popoverShow = false;
- };
- return () => (
- <NPopover
- placement={props.placement as any}
- v-model:show={state.popoverShow}
- showArrow={false}
- trigger="click"
- displayDirective="show"
- class={[styles.cascaderPopover, 'c-cascaderPopover']}>
- {{
- trigger: () => (
- <div
- class={[
- styles.nBaseCascaser,
- state.popoverShow ? styles.nBaseCascaserActive : ''
- ]}>
- <div class={styles['n-base-selection-tags']}>
- <div class={styles['n-base-selection-input']}>
- <div class={styles['n-base-selection-input__content']}>
- {valueText.value}
- </div>
- </div>
- <div class={[styles['n-base-suffix']]}>
- <div class={[styles.arrow]}>
- <img src={state.popoverShow ? arrowUp : arrowDown} />
- </div>
- </div>
- </div>
- <div
- class={[
- styles['n-base-selection-placeholder'],
- styles['n-base-selection-overlay']
- ]}>
- {!valueText.value && (
- <div class={styles.inner}>{props.placeholder}</div>
- )}
- </div>
- <div class={styles['n-base-selection__border']}></div>
- <div class={styles['n-base-selection__state-border']}></div>
- </div>
- ),
- default: () => (
- <div class={styles.baseContent}>
- <NScrollbar
- class={styles.baseScrollBar}
- style={{ maxHeight: '400px' }}>
- <div class={styles.baseContentTitle}>
- {props.options[0].columnName}
- </div>
- <div class={styles.baseContentWrap}>
- {props.options.map((subject: any) => (
- <span
- class={[
- styles.tag,
- (state.tagActiveId || '') == subject.id &&
- styles.tagActive
- ]}
- onClick={() => {
- state.tagActiveId = subject.id;
- initParentSelect(subject);
- }}>
- {subject.name}
- </span>
- ))}
- </div>
- <ChildNodeSearch
- activeRow={state.selectParents}
- onSelectChildTag={(val: any) => {
- state.childSelectId = val;
- }}
- />
- </NScrollbar>
- <div class={styles.btnGroup}>
- <div class={[styles.btn, styles.btnCancel]} onClick={onReset}>
- 重置
- </div>
- <div
- class={[styles.btn, styles.btnConfirm]}
- onClick={onConfirm}>
- 确认
- </div>
- </div>
- </div>
- )
- }}
- </NPopover>
- );
- }
- });
- const ChildNodeSearch = defineComponent({
- name: 'ChildNodeSearch',
- props: {
- activeRow: {
- type: Object,
- default: () => ({})
- },
- list: {
- type: Array,
- default: () => []
- },
- loading: {
- type: Boolean,
- default: false
- }
- },
- emits: ['selectChildTag'],
- setup(props, { emit }) {
- const { activeRow } = toRefs(props);
- const selectItem = ref({});
- watch(
- () => props.activeRow,
- () => {
- activeRow.value = props.activeRow;
- initActiveRow();
- }
- );
- const initActiveRow = () => {
- if (activeRow.value.activeIndex) {
- const childList = activeRow.value.children || [];
- childList.forEach((subject: any) => {
- if (subject.id === activeRow.value.activeIndex) {
- let children: any;
- let columnName = '';
- if (subject.children) {
- children = [
- {
- columnName: subject.children[0].columnName,
- name: '全部' + subject.children[0].columnName || '',
- id: ''
- },
- ...subject.children
- ];
- columnName = subject.children[0].columnName;
- selectItem.value = {
- ...subject,
- columnName,
- activeIndex: subject.activeIndex || '',
- children
- };
- }
- }
- });
- } else {
- selectItem.value = {};
- }
- };
- onMounted(() => {
- initActiveRow();
- });
- return () => (
- <>
- {activeRow.value?.id && (
- <>
- <div class={styles.baseContentTitle}>
- {activeRow.value.columnName}
- </div>
- <div class={styles.baseContentWrap}>
- {activeRow.value?.children.map((subject: any) => (
- <span
- class={[
- styles.tag,
- (activeRow.value.activeIndex || '') == subject.id &&
- styles.tagActive
- ]}
- onClick={() => {
- if (props.loading) return;
- activeRow.value.activeIndex = subject.id;
- let children: any;
- let columnName = '';
- if (subject.children) {
- children = [
- {
- columnName: subject.children[0].columnName,
- name: '全部' + subject.children[0].columnName || '',
- id: ''
- },
- ...subject.children
- ];
- columnName = subject.children[0].columnName;
- selectItem.value = {
- ...subject,
- columnName,
- activeIndex: '',
- children
- };
- } else {
- selectItem.value = {};
- }
- emit('selectChildTag', activeRow.value.activeIndex);
- }}>
- {subject.name}
- </span>
- ))}
- </div>
- <ChildNodeSearch
- activeRow={selectItem.value}
- onSelectChildTag={(item: any) => {
- emit('selectChildTag', item || activeRow.value.activeIndex);
- }}
- />
- </>
- )}
- </>
- );
- }
- });
|