完成小组件
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 AdderPageBack from './AdderPageBack'
|
||||||
import useLayoutStore from '../useLayoutStore'
|
import useLayoutStore from '../useLayoutStore'
|
||||||
import { OhVueIcon, addIcons } from 'oh-vue-icons'
|
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 CustomAdder from './CustomAdder'
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import ThemeProvider from '@/utils/ThemeProvider'
|
import ThemeProvider from '@/utils/ThemeProvider'
|
||||||
|
import WidgetAdder from './WidgetAdder'
|
||||||
|
import { Form, Input, Select } from 'ant-design-vue'
|
||||||
addIcons(MdKeyboardcommandkey, FaCompass, FaPencilRuler)
|
addIcons(MdKeyboardcommandkey, FaCompass, FaPencilRuler)
|
||||||
|
|
||||||
const ItemButton = defineComponent({
|
const ItemButton = defineComponent({
|
||||||
|
@ -50,10 +60,14 @@ const ItemButton = defineComponent({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const AddToToken = Symbol('addTo') as InjectionKey<Ref<number>>
|
||||||
|
|
||||||
export default defineComponent(() => {
|
export default defineComponent(() => {
|
||||||
const layout = useLayoutStore()
|
const layout = useLayoutStore()
|
||||||
const isGame = computed(() => layout.state.current === 0)
|
const isGame = computed(() => layout.state.current === 0)
|
||||||
const type = ref(1)
|
const type = ref(1)
|
||||||
|
const addTo = ref(layout.state.currentPage)
|
||||||
|
provide(AddToToken, addTo)
|
||||||
return () => (
|
return () => (
|
||||||
<div class={clsx('w-full h-full relative flex', isGame.value && 'bg-[#2c2e3e]')}>
|
<div class={clsx('w-full h-full relative flex', isGame.value && 'bg-[#2c2e3e]')}>
|
||||||
<ThemeProvider dark={isGame.value}>
|
<ThemeProvider dark={isGame.value}>
|
||||||
|
@ -96,11 +110,25 @@ export default defineComponent(() => {
|
||||||
}
|
}
|
||||||
onContextmenu={(e) => e.stopPropagation()}
|
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-0 flex-grow p-6">
|
||||||
<div class="w-full h-full relative">
|
<div class="w-full h-full relative">
|
||||||
<Transition>
|
<Transition>
|
||||||
{type.value === 0 ? '' : type.value === 1 ? '' : <CustomAdder />}
|
{type.value === 0 ? <WidgetAdder /> : type.value === 1 ? '' : <CustomAdder />}
|
||||||
</Transition>
|
</Transition>
|
||||||
</div>
|
</div>
|
||||||
</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 useLayoutStore from '../useLayoutStore'
|
||||||
import { Button, Form, Input, InputGroup } from 'ant-design-vue'
|
import { Button, Form, Input, InputGroup } from 'ant-design-vue'
|
||||||
import { OhVueIcon, addIcons } from 'oh-vue-icons'
|
import { OhVueIcon, addIcons } from 'oh-vue-icons'
|
||||||
|
@ -11,6 +11,7 @@ import type { Block } from '../layout.types'
|
||||||
import { ColorPicker } from 'vue3-colorpicker'
|
import { ColorPicker } from 'vue3-colorpicker'
|
||||||
import 'vue3-colorpicker/style.css'
|
import 'vue3-colorpicker/style.css'
|
||||||
import { globalToast } from '@/main'
|
import { globalToast } from '@/main'
|
||||||
|
import { AddToToken } from './AdderPage'
|
||||||
|
|
||||||
addIcons(MdUpload, MdImage, MdCheck)
|
addIcons(MdUpload, MdImage, MdCheck)
|
||||||
|
|
||||||
|
@ -150,6 +151,7 @@ export default defineComponent(() => {
|
||||||
if (val.name) form.name = val.name
|
if (val.name) form.name = val.name
|
||||||
if (val.icon) form.icon = val.icon
|
if (val.icon) form.icon = val.icon
|
||||||
})
|
})
|
||||||
|
const addTo = inject(AddToToken)
|
||||||
return () => (
|
return () => (
|
||||||
<div
|
<div
|
||||||
class={
|
class={
|
||||||
|
@ -242,7 +244,7 @@ export default defineComponent(() => {
|
||||||
form.type === 0 ? '' : form.text || form.name.substring(0, 2).toLocaleUpperCase(),
|
form.type === 0 ? '' : form.text || form.name.substring(0, 2).toLocaleUpperCase(),
|
||||||
label: form.name
|
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 addBlock = (block: Block, _page: number = -1) => {
|
||||||
const page = _page >= 0 ? _page : state.currentPage
|
const page = _page >= 0 ? _page : state.currentPage
|
||||||
|
console.log(page)
|
||||||
console.log(state.content[state.current].pages[page])
|
console.log(state.content[state.current].pages[page])
|
||||||
if (!state.content[state.current].pages[page]) {
|
if (!state.content[state.current].pages[page]) {
|
||||||
globalToast.warning('请先添加页面')
|
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