完成小组件
This commit is contained in:
parent
b9dc48751f
commit
acc091644c
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
|
@ -1,4 +1,12 @@
|
|||
import { computed, defineComponent, ref, Transition } from 'vue'
|
||||
import {
|
||||
computed,
|
||||
defineComponent,
|
||||
provide,
|
||||
ref,
|
||||
Transition,
|
||||
type InjectionKey,
|
||||
type Ref
|
||||
} from 'vue'
|
||||
import AdderPageBack from './AdderPageBack'
|
||||
import useLayoutStore from '../useLayoutStore'
|
||||
import { OhVueIcon, addIcons } from 'oh-vue-icons'
|
||||
|
@ -6,6 +14,8 @@ import { MdKeyboardcommandkey, FaCompass, FaPencilRuler } from 'oh-vue-icons/ico
|
|||
import CustomAdder from './CustomAdder'
|
||||
import clsx from 'clsx'
|
||||
import ThemeProvider from '@/utils/ThemeProvider'
|
||||
import WidgetAdder from './WidgetAdder'
|
||||
import { Form, Input, Select } from 'ant-design-vue'
|
||||
addIcons(MdKeyboardcommandkey, FaCompass, FaPencilRuler)
|
||||
|
||||
const ItemButton = defineComponent({
|
||||
|
@ -50,10 +60,14 @@ const ItemButton = defineComponent({
|
|||
}
|
||||
})
|
||||
|
||||
export const AddToToken = Symbol('addTo') as InjectionKey<Ref<number>>
|
||||
|
||||
export default defineComponent(() => {
|
||||
const layout = useLayoutStore()
|
||||
const isGame = computed(() => layout.state.current === 0)
|
||||
const type = ref(1)
|
||||
const addTo = ref(layout.state.currentPage)
|
||||
provide(AddToToken, addTo)
|
||||
return () => (
|
||||
<div class={clsx('w-full h-full relative flex', isGame.value && 'bg-[#2c2e3e]')}>
|
||||
<ThemeProvider dark={isGame.value}>
|
||||
|
@ -96,11 +110,25 @@ export default defineComponent(() => {
|
|||
}
|
||||
onContextmenu={(e) => e.stopPropagation()}
|
||||
>
|
||||
<div class="w-full h-[60px]"></div>
|
||||
<Form class="w-full px-4 mt-4" layout="inline">
|
||||
<Form.Item label="添加到">
|
||||
<Select
|
||||
style="width: 140px"
|
||||
v-model:value={addTo.value}
|
||||
options={layout.currentMode.pages.map((el, idx) => ({
|
||||
label: el.label,
|
||||
value: idx
|
||||
}))}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
<Input.Search class="w-[200px]" placeholder="搜索组件或网站" />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
<div class="w-full h-0 flex-grow p-6">
|
||||
<div class="w-full h-full relative">
|
||||
<Transition>
|
||||
{type.value === 0 ? '' : type.value === 1 ? '' : <CustomAdder />}
|
||||
{type.value === 0 ? <WidgetAdder /> : type.value === 1 ? '' : <CustomAdder />}
|
||||
</Transition>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { computed, defineComponent, reactive, ref, watch } from 'vue'
|
||||
import { computed, defineComponent, inject, reactive, ref, watch } from 'vue'
|
||||
import useLayoutStore from '../useLayoutStore'
|
||||
import { Button, Form, Input, InputGroup } from 'ant-design-vue'
|
||||
import { OhVueIcon, addIcons } from 'oh-vue-icons'
|
||||
|
@ -11,6 +11,7 @@ import type { Block } from '../layout.types'
|
|||
import { ColorPicker } from 'vue3-colorpicker'
|
||||
import 'vue3-colorpicker/style.css'
|
||||
import { globalToast } from '@/main'
|
||||
import { AddToToken } from './AdderPage'
|
||||
|
||||
addIcons(MdUpload, MdImage, MdCheck)
|
||||
|
||||
|
@ -150,6 +151,7 @@ export default defineComponent(() => {
|
|||
if (val.name) form.name = val.name
|
||||
if (val.icon) form.icon = val.icon
|
||||
})
|
||||
const addTo = inject(AddToToken)
|
||||
return () => (
|
||||
<div
|
||||
class={
|
||||
|
@ -242,7 +244,7 @@ export default defineComponent(() => {
|
|||
form.type === 0 ? '' : form.text || form.name.substring(0, 2).toLocaleUpperCase(),
|
||||
label: form.name
|
||||
}
|
||||
layout.addBlock(data)
|
||||
layout.addBlock(data, addTo?.value)
|
||||
}}
|
||||
>
|
||||
确定
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
import { computed, defineComponent } from 'vue'
|
||||
import useLayoutStore from '../useLayoutStore'
|
||||
import widgetList, { type Widget } from '@/widgets'
|
||||
import { Button } from 'ant-design-vue'
|
||||
import clsx from 'clsx'
|
||||
|
||||
export const Item = defineComponent({
|
||||
props: {
|
||||
content: {
|
||||
type: Object as () => Widget,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
setup(props) {
|
||||
const layout = useLayoutStore()
|
||||
const isGame = computed(() => layout.state.current === 0)
|
||||
return () => (
|
||||
<div
|
||||
class={clsx('bg-white w-full h-full rounded-lg shadow p-4', {
|
||||
'bg-white/20': isGame.value,
|
||||
'bg-white/80': !isGame.value
|
||||
})}
|
||||
key={props.content.name}
|
||||
>
|
||||
<div class="flex">
|
||||
<img src={props.content.icon} class="w-[48px] h-[48px] bg-cover" />
|
||||
<div class="px-2 w-0 flex-grow">
|
||||
<div
|
||||
class={clsx('text text-sm', {
|
||||
'text-white': isGame.value,
|
||||
'text-black/80': !isGame.value
|
||||
})}
|
||||
>
|
||||
{props.content.label}
|
||||
</div>
|
||||
<div
|
||||
class={clsx('text-[12px]', {
|
||||
'text-white/80': isGame.value,
|
||||
'text-black/60': !isGame.value
|
||||
})}
|
||||
>
|
||||
{props.content.description}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end">
|
||||
<Button size="small" type="primary">
|
||||
添加
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
export default defineComponent(() => {
|
||||
return () => (
|
||||
<div class="absolute left-0 top-0 w-full h-full overflow-y-auto gap-4">
|
||||
<div
|
||||
class="w-full grid grid-cols-3 grid-flow-row-dense pb-[200px]"
|
||||
style="grid-auto-rows: 100px"
|
||||
>
|
||||
{widgetList.map((el) => (
|
||||
<Item content={el} key={el.name} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
|
@ -64,6 +64,7 @@ export default defineStore('layout', () => {
|
|||
// 添加图标
|
||||
const addBlock = (block: Block, _page: number = -1) => {
|
||||
const page = _page >= 0 ? _page : state.currentPage
|
||||
console.log(page)
|
||||
console.log(state.content[state.current].pages[page])
|
||||
if (!state.content[state.current].pages[page]) {
|
||||
globalToast.warning('请先添加页面')
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
import { defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent(() => {
|
||||
return () => <div class="w-full h-full bg-red-50"></div>
|
||||
})
|
|
@ -0,0 +1,5 @@
|
|||
import { defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent(() => {
|
||||
return () => <div class="w-full h-full bg-red-50"></div>
|
||||
})
|
|
@ -0,0 +1,5 @@
|
|||
import { defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent(() => {
|
||||
return () => <div class="w-full h-full bg-red-50"></div>
|
||||
})
|
|
@ -0,0 +1,5 @@
|
|||
import { defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent(() => {
|
||||
return () => <div class="w-full h-full bg-red-50"></div>
|
||||
})
|
|
@ -0,0 +1,29 @@
|
|||
import type { Widget } from '..'
|
||||
|
||||
export default {
|
||||
name: 'calendar',
|
||||
label: '日历',
|
||||
description: '日历信息',
|
||||
icon: '/icons/calendarIcon.png',
|
||||
modal: () => import('./Modal'),
|
||||
list: [
|
||||
{
|
||||
w: 2,
|
||||
h: 1,
|
||||
label: '小',
|
||||
component: () => import('./Small')
|
||||
},
|
||||
{
|
||||
w: 2,
|
||||
h: 2,
|
||||
label: '中',
|
||||
component: () => import('./Middle')
|
||||
},
|
||||
{
|
||||
w: 4,
|
||||
h: 2,
|
||||
label: '大',
|
||||
component: () => import('./Large')
|
||||
}
|
||||
]
|
||||
} as Widget
|
|
@ -0,0 +1,17 @@
|
|||
import calendar from './calendar'
|
||||
|
||||
export interface Widget {
|
||||
name: string // 小组件类型唯一标识
|
||||
label: string // 小组件名称
|
||||
description: string // 小组件描述
|
||||
icon: string // 小组件图标
|
||||
modal: () => any // 弹框组件
|
||||
list: {
|
||||
w: number
|
||||
h: number
|
||||
label: string
|
||||
component: () => any
|
||||
}[] // 不同尺寸小组件块
|
||||
}
|
||||
|
||||
export default [calendar] as Widget[]
|
Loading…
Reference in New Issue