diff --git a/packages/devui-vue/devui/accordion/src/accordion-item-hreflink.tsx b/packages/devui-vue/devui/accordion/src/accordion-item-hreflink.tsx
new file mode 100644
index 0000000000..9ac9501716
--- /dev/null
+++ b/packages/devui-vue/devui/accordion/src/accordion-item-hreflink.tsx
@@ -0,0 +1,127 @@
+import { defineComponent, toRefs, computed, inject } from 'vue'
+import { accordionProps } from './accordion-types'
+import { AccordionItemClickEvent, AccordionMenuItem, AccordionLinkableItem } from './accordion.type'
+import DAccordionItem from './accordion-item'
+import { getRootSlots } from './utils'
+
+export default defineComponent({
+ name: 'DAccordionItemHreflink',
+ component: {
+ DAccordionItem
+ },
+ props: {
+ item: Object as () => AccordionLinkableItem,
+ deepth: {
+ type: Number,
+ default: 0
+ },
+ parent: {
+ type: Object as () => AccordionMenuItem,
+ default: null
+ },
+ ...accordionProps
+ },
+ setup(props) {
+ const {
+ item,
+ deepth,
+ parent,
+ titleKey,
+ linkKey,
+ linkTargetKey,
+ linkDefaultTarget,
+ // activeKey,
+ disabledKey,
+ itemTemplate
+ } = toRefs(props)
+
+ const rootSlots = getRootSlots()
+ const accordionCtx = inject('accordionContext') as any
+
+ const title = computed(() => {
+ return item.value && item.value[titleKey.value]
+ })
+
+ const link = computed(() => {
+ return item.value && item.value[linkKey.value]
+ })
+
+ // const active = computed(() => {
+ // return item.value && item.value[activeKey.value]
+ // })
+
+ // const childActived = computed(() => {
+ // return active.value
+ // })
+
+ const target = computed(() => {
+ return item.value && (item.value[linkTargetKey.value] || linkDefaultTarget.value)
+ })
+
+ const disabled = computed(() => {
+ return item.value && item.value[disabledKey.value]
+ })
+
+ const parentValue = parent.value
+ const deepValue = deepth.value
+
+ const linkItemClickFn = (itemEvent: AccordionItemClickEvent) => {
+ if (item.value && !disabled.value) {
+ accordionCtx.itemClickFn(itemEvent)
+ }
+ }
+
+ const renderContent = () => {
+ return (
+ <>
+
+ {(!rootSlots.itemTemplate || itemTemplate.value === false) && <>{title.value}>}
+ {rootSlots.itemTemplate &&
+ itemTemplate.value !== false &&
+ rootSlots.itemTemplate?.({
+ parent: parentValue,
+ deepth: deepValue,
+ item: item.value
+ })}
+ >
+ )
+ }
+
+ return () => {
+ return (
+ <>
+
+ >
+ )
+ }
+ }
+})
diff --git a/packages/devui-vue/devui/accordion/src/accordion-item-routerlink.tsx b/packages/devui-vue/devui/accordion/src/accordion-item-routerlink.tsx
new file mode 100644
index 0000000000..44e55522bb
--- /dev/null
+++ b/packages/devui-vue/devui/accordion/src/accordion-item-routerlink.tsx
@@ -0,0 +1,147 @@
+import { defineComponent, toRefs, computed, inject } from 'vue'
+import { useRoute } from 'vue-router'
+import { accordionProps } from './accordion-types'
+import { AccordionItemClickEvent, AccordionMenuItem, AccordionLinkableItem } from './accordion.type'
+import DAccordionItem from './accordion-item'
+import { getRootSlots } from './utils'
+
+export default defineComponent({
+ name: 'DAccordionItemRouterlink',
+ component: {
+ DAccordionItem
+ },
+ props: {
+ item: Object as () => AccordionLinkableItem,
+ deepth: {
+ type: Number,
+ default: 0
+ },
+ parent: {
+ type: Object as () => AccordionMenuItem,
+ default: null
+ },
+ ...accordionProps
+ },
+ setup(props) {
+ const {
+ item,
+ deepth,
+ parent,
+ titleKey,
+ linkKey,
+ linkDefaultTarget,
+ disabledKey,
+ itemTemplate
+ } = toRefs(props)
+
+ const route = useRoute()
+ const rootSlots = getRootSlots()
+ const accordionCtx = inject('accordionContext') as any
+ console.log(useRoute())
+
+ const title = computed(() => {
+ return item.value && item.value[titleKey.value]
+ })
+
+ const link = computed(() => {
+ return item.value && item.value[linkKey.value]
+ })
+
+ const isUsedVueRouter = computed(() => route !== undefined)
+
+ const routerLinkActive = computed(() => {
+ return route === link.value
+ })
+
+ const disabled = computed(() => {
+ return item.value && item.value[disabledKey.value]
+ })
+
+ const parentValue = parent.value
+ const deepValue = deepth.value
+
+ const linkItemClickFn = (itemEvent: AccordionItemClickEvent) => {
+ if (item.value && !disabled.value) {
+ accordionCtx.itemClickFn(itemEvent)
+ }
+ }
+
+ const renderContent = () => {
+ return (
+ <>
+
+ {(!rootSlots.itemTemplate || itemTemplate.value === false) && <>{title.value}>}
+ {rootSlots.itemTemplate &&
+ itemTemplate.value !== false &&
+ rootSlots.itemTemplate?.({
+ parent: parentValue,
+ deepth: deepValue,
+ item: item.value
+ })}
+ >
+ )
+ }
+
+ return () => {
+ return (
+ <>
+
+ >
+ )
+ }
+ }
+})
diff --git a/packages/devui-vue/devui/accordion/src/accordion-list.tsx b/packages/devui-vue/devui/accordion/src/accordion-list.tsx
index 8c3d05cfa1..e079dcc030 100644
--- a/packages/devui-vue/devui/accordion/src/accordion-list.tsx
+++ b/packages/devui-vue/devui/accordion/src/accordion-list.tsx
@@ -1,12 +1,9 @@
-import {
- computed,
- defineComponent,
- inject,
- toRefs
-} from 'vue'
+import { computed, defineComponent, inject, toRefs } from 'vue'
import type { AccordionMenuItem } from './accordion.type'
import DAccordionMenu from './accordion-menu'
import DAccordionItem from './accordion-item'
+import DAccordionItemHreflink from './accordion-item-hreflink'
+import DAccordionItemRouterlink from './accordion-item-routerlink'
import { accordionProps } from './accordion-types'
import { getRootSlots } from '../src/utils'
@@ -14,7 +11,9 @@ export default defineComponent({
name: 'DAccordionList',
components: {
DAccordionMenu,
- DAccordionItem
+ DAccordionItem,
+ DAccordionItemHreflink,
+ DAccordionItemRouterlink
},
inheritAttrs: false,
props: {
@@ -44,6 +43,7 @@ export default defineComponent({
showNoContent,
loadingKey,
titleKey,
+ linkTypeKey,
loadingTemplate,
noContentTemplate,
innerListTemplate
@@ -59,6 +59,7 @@ export default defineComponent({
const loading = computed(() => {
return parentValue && parentValue[loadingKey.value]
})
+
const noContent = computed(() => {
const dataValue = data.value
return dataValue === undefined || dataValue === null || dataValue.length === 0
@@ -67,7 +68,9 @@ export default defineComponent({
return () => {
return (
<>
- {(!rootSlots.innerListTemplate || deepth.value === 0 || innerListTemplate.value === false) && (
+ {(!rootSlots.innerListTemplate ||
+ deepth.value === 0 ||
+ innerListTemplate.value === false) && (
{data.value.map((item) => {
return (
@@ -89,12 +92,60 @@ export default defineComponent({
{/* 普通类型 */}
{(!linkType.value || linkType.value === '') && (
)}
+ {/* 路由链接类型 */}
+ {linkType.value === 'routerLink' && (
+
+ )}
+ {/* 普通链接类型 */}
+ {linkType.value === 'hrefLink' && (
+
+ )}
+ {/* 动态链接类型 */}
+ {linkType.value === 'dependOnLinkTypeKey' && (
+ <>
+ {item[linkTypeKey.value] === 'routerLink' && (
+
+ )}
+ {item[linkTypeKey.value] === 'hrefLink' && (
+
+ )}
+ {item[linkTypeKey.value] !== 'routerLink' &&
+ item[linkTypeKey.value] !== 'hrefLink' && (
+
+ )}
+ >
+ )}
>
)}
@@ -130,7 +181,7 @@ export default defineComponent({
{
// 自定义加载
loading.value &&
- rootSlots.loadingTemplate &&
+ rootSlots.loadingTemplate &&
loadingTemplate.value !== false &&
rootSlots.loadingTemplate?.({
item: parentValue,
diff --git a/packages/devui-vue/devui/accordion/src/composables/use-active.ts b/packages/devui-vue/devui/accordion/src/composables/use-active.ts
deleted file mode 100644
index 0ed36c8eaa..0000000000
--- a/packages/devui-vue/devui/accordion/src/composables/use-active.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-import { ref, Ref, toRefs } from 'vue'
-import { AccordionProps } from '../accordion-types'
-import { AccordionItemClickEvent, AccordionMenuItem } from '../accordion.type'
-
-import { flatten } from '../utils'
-
-type activeObjectRef = {
- [key: string]: {
- isDisable: boolean
- isActive: boolean
- }
-}
-
-type TypeUseActive = (
- props: AccordionProps,
- emit: (arg0: string, arg1: AccordionMenuItem) => void
-) => {
- activeObjectRef: Ref
- prevActiveItemIdRef: Ref
- initActiveItem: (item: AccordionMenuItem) => void
- activeItemFn: (item: AccordionMenuItem) => void
- // itemClickFn: (itemEvent: AccordionItemClickEvent) => void
- // linkItemClickFn: (itemEvent: AccordionItemClickEvent) => void
-}
-
-const useActive: TypeUseActive = (props, emit) => {
- const { activeKey, disabledKey } = toRefs(props)
- const activeObjectRef: Ref = ref({})
- const prevActiveItemIdRef: Ref = ref(null) //记录用户点击的激活菜单项
-
- const initActiveItem = (item) => {
- activeObjectRef.value[item.id] = {
- isDisable: item[disabledKey.value],
- isActive: item[activeKey.value]
- }
- if (item[activeKey.value]) {
- prevActiveItemIdRef.value = item.id
- }
- }
-
- // 激活子菜单项并去掉其他子菜单的激活
- const activeItemFn = (item: AccordionMenuItem) => {
- if (activeObjectRef.value[item.id].isDisable) return
- if (prevActiveItemIdRef.value === item.id) return
- if (prevActiveItemIdRef.value) {
- activeObjectRef.value[prevActiveItemIdRef.value].isActive = false
- }
- activeObjectRef.value[item.id].isActive = true
- prevActiveItemIdRef.value = item.id
- emit('activeItemChange', item)
- }
-
- // 点击了可点击菜单
- // const itemClickFn = (itemEvent: AccordionItemClickEvent) => {
- // const prevActiveItemIdRef = clickActiveItem
- // activeItemFn(itemEvent.item)
- // // emit('itemClick', {...itemEvent, prevActiveItem: prevActiveItem});
- // }
-
- // const linkItemClickFn = (itemEvent: AccordionItemClickEvent) => {
- // const prevActiveItem = clickActiveItem
- // clickActiveItem.value = itemEvent.item
- // // emit('itemClick', {...itemEvent, prevActiveItem: prevActiveItem});
- // }
-
- return {
- activeObjectRef,
- prevActiveItemIdRef,
- initActiveItem,
- activeItemFn
- // itemClickFn,
- // linkItemClickFn
- }
-}
-
-export default useActive
diff --git a/packages/devui-vue/devui/accordion/src/composables/use-toggle.ts b/packages/devui-vue/devui/accordion/src/composables/use-toggle.ts
deleted file mode 100644
index 646175ef9b..0000000000
--- a/packages/devui-vue/devui/accordion/src/composables/use-toggle.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-import { toRefs, ref } from 'vue'
-import { AccordionMenuItem, AccordionMenuToggleEvent } from '../accordion.type'
-import { flatten } from '../utils'
-
-type TypeMenuOpenStatusRef = {
- [key: string]: {
- isOpen: boolean
- }
-}
-
-const useToggle = (props) => {
- const menuOpenStatusRef = ref({})
- const preOpenFoldeRef = ref('')
- const { data, childrenKey, openKey, restrictOneOpen } = toRefs(props)
-
- const initAllOpenData = (item) => {
- menuOpenStatusRef.value[item.id] = {
- isOpen: item[openKey.value]
- }
- if (item[openKey.value]) {
- preOpenFoldeRef.value = item.id
- }
- }
-
- // 打开或关闭一级菜单,如果有限制只能展开一项则关闭其他一级菜单
- const openMenuFn = (item, open) => {
- if (open && restrictOneOpen.value) {
- if (preOpenFoldeRef.value === item.id) return
- if (preOpenFoldeRef.value) {
- menuOpenStatusRef.value[preOpenFoldeRef.value].isOpen = false
- }
- }
- menuOpenStatusRef.value[item.id].isOpen = open
- }
-
- // 打开或关闭可折叠菜单
- const menuToggleFn = (menuEvent: AccordionMenuToggleEvent) => {
- openMenuFn(menuEvent.item, menuEvent.open)
- }
-
- const cleanOpenData = () => {
- flatten(data.value, childrenKey.value, true, false).forEach(
- (item) => (item[openKey.value] = undefined)
- )
- }
-
- return {
- menuOpenStatusRef,
- initAllOpenData,
- openMenuFn,
- menuToggleFn,
- cleanOpenData
- }
-}
-
-export default useToggle
diff --git a/packages/devui-vue/docs/components/accordion/index.md b/packages/devui-vue/docs/components/accordion/index.md
index a25613266c..1f26155926 100644
--- a/packages/devui-vue/docs/components/accordion/index.md
+++ b/packages/devui-vue/docs/components/accordion/index.md
@@ -1,114 +1,126 @@
# Accordion 手风琴
+
为页面提供导航的组件。
+
### 何时使用
+
需要通过分组组织菜单的时候使用。
### 基本用法
-传入菜单,监听含子项的可展开菜单的开合事件(menuToggle)或可点击菜单的点击事件(itemClick)。可展开菜单默认展开使用属性open,可点击菜单默认激活使用属性active,禁用项使用disabled。通过restrictOneOpen设置是否限制只能展开一个一级菜单。
+
+传入菜单,监听含子项的可展开菜单的开合事件(menuToggle)或可点击菜单的点击事件(itemClick)。可展开菜单默认展开使用属性 open,可点击菜单默认激活使用属性 active,禁用项使用 disabled。通过 restrictOneOpen 设置是否限制只能展开一个一级菜单。
:::demo
```vue
-
-
-
- Only one level-1 menu can be expanded.
-
- Embedded menu (no shadow)
+
+
+
+
+ Only one level-1 menu can be expanded.
+
+
+
+
+ Embedded menu (no shadow)
+
+
```
-
:::
+### 使用内置路由和链接类型
-### 使用模板
-可展开菜单和可点击菜单分别使用模板。可展开菜单指定menuItemTemplate,可点击菜单指定itemTemplate。没有数据模板指定noContentTemplate,并可以通过showNoContent控制无数据的时候不展开。 加载中模板指定loadingTemplate,通过item的loadingKey对应的属性值控制是否显示加载中。
+通过设置 linkType 切换不同的内置路由和链接类型:默认类型'';路由类型'routerLink';外链类型:'hrefLink';基于数据判断路由或链接类型:'dependOnLinkTypeKey'。
:::demo
+```vue
+
+
+
+
+
+
+
+```
+
+:::
+
+### 使用模板
+
+可展开菜单和可点击菜单分别使用模板。可展开菜单指定 menuItemTemplate,可点击菜单指定 itemTemplate。没有数据模板指定 noContentTemplate,并可以通过 showNoContent 控制无数据的时候不展开。 加载中模板指定 loadingTemplate,通过 item 的 loadingKey 对应的属性值控制是否显示加载中。
+
+:::demo
```vue
-
+ reset
+
+
+
+
+ {{ item.title }}
+ (Click Count: {{ item.clicktimes || '0' }})
+
+
+ -
+
+ Not available yet. Please wait.
+
+
+
+
+
+ -
+
+
+ loading...
+
+
+
+
+
+