完成今天吃什么小组件的开发
This commit is contained in:
parent
91f8b1a229
commit
f86c26b823
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.6 KiB |
|
@ -0,0 +1,143 @@
|
||||||
|
import clsx from 'clsx'
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
import { defineComponent, ref } from 'vue'
|
||||||
|
|
||||||
|
export default defineComponent(() => {
|
||||||
|
const list = [
|
||||||
|
'猪脚饭',
|
||||||
|
'汉堡薯条',
|
||||||
|
'麻辣烫',
|
||||||
|
'烧腊饭',
|
||||||
|
'黄焖鸡米饭',
|
||||||
|
'煲仔饭 ',
|
||||||
|
'酸辣粉',
|
||||||
|
'肠粉',
|
||||||
|
'沙县小吃',
|
||||||
|
'热干面',
|
||||||
|
'重庆小面 ',
|
||||||
|
'兰州拉面',
|
||||||
|
'凉皮',
|
||||||
|
'生煎',
|
||||||
|
'锅贴',
|
||||||
|
'炒饭',
|
||||||
|
'冒菜',
|
||||||
|
'鸭血粉丝汤',
|
||||||
|
'胡辣汤',
|
||||||
|
'砂锅粥',
|
||||||
|
'螺蛳粉',
|
||||||
|
'水饺',
|
||||||
|
'茶餐厅',
|
||||||
|
'馄饨抄手',
|
||||||
|
'披萨',
|
||||||
|
'桂林米粉',
|
||||||
|
'川菜',
|
||||||
|
'湘菜',
|
||||||
|
'粤菜',
|
||||||
|
'日本料理',
|
||||||
|
'韩国料理',
|
||||||
|
'焗饭',
|
||||||
|
'泡面',
|
||||||
|
'麻辣香锅',
|
||||||
|
'沙拉轻食',
|
||||||
|
'馄饨',
|
||||||
|
'拉面',
|
||||||
|
'烩面',
|
||||||
|
'热干面',
|
||||||
|
'刀削面',
|
||||||
|
'油泼面',
|
||||||
|
'炸酱面',
|
||||||
|
'炒面',
|
||||||
|
'米线',
|
||||||
|
'酸辣粉',
|
||||||
|
'土豆粉',
|
||||||
|
'螺狮粉',
|
||||||
|
'凉皮儿',
|
||||||
|
'麻辣烫',
|
||||||
|
'肉夹馍',
|
||||||
|
'羊肉汤',
|
||||||
|
'炒饭',
|
||||||
|
'盖浇饭',
|
||||||
|
'卤肉饭',
|
||||||
|
'烤肉饭',
|
||||||
|
'黄焖鸡米饭',
|
||||||
|
'驴肉火烧',
|
||||||
|
'川菜',
|
||||||
|
'麻辣香锅',
|
||||||
|
'火锅',
|
||||||
|
'酸菜鱼',
|
||||||
|
'烤串',
|
||||||
|
'披萨',
|
||||||
|
'烤鸭',
|
||||||
|
'汉堡',
|
||||||
|
'炸鸡',
|
||||||
|
'寿司',
|
||||||
|
'蟹黄包',
|
||||||
|
'煎饼果子',
|
||||||
|
'生煎',
|
||||||
|
'炒年糕'
|
||||||
|
]
|
||||||
|
const text = ref('')
|
||||||
|
return () => (
|
||||||
|
<div
|
||||||
|
class="w-full h-full flex flex-col px-[14px] pt-[23px]"
|
||||||
|
style={{
|
||||||
|
backgroundImage: `url('/bg/eat_bg@2x.webp')`,
|
||||||
|
backgroundSize: '100% 100%'
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
text.value = ''
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div class={'w-full flex justify-center'}>
|
||||||
|
<img src="/bg/eat_top_bg.webp" alt="eat_bg"></img>
|
||||||
|
</div>
|
||||||
|
<div class={'flex flex-col w-full justify-center items-center'}>
|
||||||
|
<div
|
||||||
|
class={clsx(
|
||||||
|
'w-[130px] duration-150 bg-white relative',
|
||||||
|
text.value ? 'h-[120px]' : 'h-[17px]'
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class={
|
||||||
|
'w-[48px] h-[19px] text-[12px] rounded left-1/2 bottom-[-10px] absolute -translate-x-1/2 rounded-br-[6px] rounded-bl-[6px] text-white'
|
||||||
|
}
|
||||||
|
style={{
|
||||||
|
background: 'linear-gradient(180deg,#ffa061 0%,#ffb62f 100%)',
|
||||||
|
boxShadow: 'inset 0 0 2px #ff640080'
|
||||||
|
}}
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation()
|
||||||
|
const index = Math.floor(Math.random() * list.length)
|
||||||
|
if (text.value) {
|
||||||
|
text.value = ''
|
||||||
|
setTimeout(() => {
|
||||||
|
text.value = list[index]
|
||||||
|
}, 400)
|
||||||
|
}else {
|
||||||
|
text.value = list[index]
|
||||||
|
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{text.value ? '换' : '开始'}
|
||||||
|
</button>
|
||||||
|
<span
|
||||||
|
class={
|
||||||
|
'text-[12px] text-[#333] absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{text.value}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{!text.value && (
|
||||||
|
<>
|
||||||
|
<span class={'text-[24px] mt-[24px] text-[#333]'}>今天吃什么</span>
|
||||||
|
<span class={'mb-[2px] text-[12px] text-[#666]'}>{dayjs().format('MM.DD')}</span>
|
||||||
|
<span class="text-[12px] text-[#999]">{dayjs().format('ddd')}</span>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})
|
|
@ -0,0 +1,12 @@
|
||||||
|
import { defineComponent } from 'vue'
|
||||||
|
|
||||||
|
export default defineComponent(() => {
|
||||||
|
return () => (
|
||||||
|
<div
|
||||||
|
class="w-full h-full bg-red-50 flex "
|
||||||
|
style={{
|
||||||
|
background: 'linear-gradient(180deg,#dcefff 0%,#e7ecff 100%)'
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
)
|
||||||
|
})
|
|
@ -0,0 +1,20 @@
|
||||||
|
import asyncLoader from '@/utils/asyncLoader'
|
||||||
|
import type { Widget } from '..'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'todayEat',
|
||||||
|
label: '今天吃什么',
|
||||||
|
description: '今天吃什么呢?',
|
||||||
|
icon: '/icons/today_eat.png',
|
||||||
|
modal: null,
|
||||||
|
list: [
|
||||||
|
|
||||||
|
{
|
||||||
|
w: 2,
|
||||||
|
h: 2,
|
||||||
|
label: '中',
|
||||||
|
component: asyncLoader(() => import('./Middle'))
|
||||||
|
},
|
||||||
|
|
||||||
|
]
|
||||||
|
} as Widget
|
|
@ -3,6 +3,7 @@ import calendar from './calendar'
|
||||||
import weather from './weather'
|
import weather from './weather'
|
||||||
import weApply from './weApply'
|
import weApply from './weApply'
|
||||||
import gameNews from './gameNews'
|
import gameNews from './gameNews'
|
||||||
|
import eat from './eat'
|
||||||
export interface Widget {
|
export interface Widget {
|
||||||
name: string // 小组件类型唯一标识
|
name: string // 小组件类型唯一标识
|
||||||
label: string // 小组件名称
|
label: string // 小组件名称
|
||||||
|
@ -17,4 +18,4 @@ export interface Widget {
|
||||||
}[] // 不同尺寸小组件块
|
}[] // 不同尺寸小组件块
|
||||||
}
|
}
|
||||||
|
|
||||||
export default [calendar, weather, weApply, gameNews] as Widget[]
|
export default [calendar, weather, weApply, gameNews, eat] as Widget[]
|
||||||
|
|
|
@ -1,172 +1,9 @@
|
||||||
import { defineComponent, ref, watch, type VNodeRef } from 'vue'
|
import { defineComponent } from 'vue'
|
||||||
import { useWeApplyStore } from './useWeApplyStore'
|
|
||||||
import { addIcons, OhVueIcon } from 'oh-vue-icons'
|
|
||||||
import { HiChevronDown } from 'oh-vue-icons/icons'
|
|
||||||
import clsx from 'clsx'
|
|
||||||
addIcons(HiChevronDown)
|
|
||||||
export default defineComponent(() => {
|
export default defineComponent(() => {
|
||||||
const store = useWeApplyStore()
|
|
||||||
const gameRef = ref<VNodeRef | null>(null)
|
|
||||||
const isGameBottom = ref(false)
|
|
||||||
const isWorkBottom = ref(false)
|
|
||||||
const workRef = ref<VNodeRef | null>(null)
|
|
||||||
const computIsBottom = (ref: any) => {
|
|
||||||
if (ref) {
|
|
||||||
const { scrollTop, clientHeight, scrollHeight } = ref
|
|
||||||
return scrollTop + clientHeight >= scrollHeight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const handleGameScroll = () => {
|
|
||||||
const isAtBottom = computIsBottom(gameRef.value)
|
|
||||||
console.log(isAtBottom ? '已滚动到底部!' : '未滚动到底部。')
|
|
||||||
if (isAtBottom) {
|
|
||||||
isGameBottom.value = true
|
|
||||||
} else {
|
|
||||||
isGameBottom.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const handleWorkScroll = () => {
|
|
||||||
const isAtBottom = computIsBottom(workRef.value)
|
|
||||||
console.log(isAtBottom ? '已滚动到底部!' : '未滚动到底部。')
|
|
||||||
if (isAtBottom) {
|
|
||||||
isWorkBottom.value = true
|
|
||||||
} else {
|
|
||||||
isWorkBottom.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
watch(gameRef, (val, _, onCleanup) => {
|
|
||||||
console.log(val)
|
|
||||||
if (!val) return
|
|
||||||
val.addEventListener('scroll', handleGameScroll)
|
|
||||||
// if (val + gameRef.value.clientHeight >= gameRef.value.scrollHeight) {
|
|
||||||
// isGameBottom.value = true
|
|
||||||
// } else {
|
|
||||||
// isGameBottom.value = false
|
|
||||||
// }
|
|
||||||
onCleanup(() => {
|
|
||||||
val.removeEventListener('scroll', handleGameScroll)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
watch(workRef, (val, _, onCleanup) => {
|
|
||||||
console.log(val)
|
|
||||||
if (!val) return
|
|
||||||
|
|
||||||
val.addEventListener('scroll', handleWorkScroll)
|
|
||||||
// if (val + gameRef.value.clientHeight >= gameRef.value.scrollHeight) {
|
|
||||||
// isGameBottom.value = true
|
|
||||||
// } else {
|
|
||||||
// isGameBottom.value = false
|
|
||||||
// }
|
|
||||||
onCleanup(() => {
|
|
||||||
val.removeEventListener('scroll', handleWorkScroll)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
return () => (
|
return () => (
|
||||||
<div
|
<div class="w-full h-full bg-[#ecfbff] flex flex-col">
|
||||||
class={'w-full h-full flex p-2 justify-between'}
|
large
|
||||||
style={{
|
|
||||||
background: 'rgba(23,33,45,.6)'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class={'w-[49.5%] h-full rounded-xl p-2 relative overflow-hidden'}
|
|
||||||
style={{
|
|
||||||
background: 'rgba(23,33,46,.8)'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{!isGameBottom.value && (
|
|
||||||
<div
|
|
||||||
class={
|
|
||||||
'w-full absolute bottom-0 left-0 flex justify-center bg-[#17212e] h-[20px] items-center'
|
|
||||||
}
|
|
||||||
onClick={(e) => {
|
|
||||||
e.stopPropagation()
|
|
||||||
e.preventDefault()
|
|
||||||
if (gameRef.value) {
|
|
||||||
gameRef.value.scrollTop += 40
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<OhVueIcon name={HiChevronDown.name} fill="#ddd"></OhVueIcon>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div
|
|
||||||
ref={gameRef}
|
|
||||||
class={clsx('w-full h-full flex flex-col overflow-y-scroll gap-y-2 scrollbar-hide ')}
|
|
||||||
onWheel={() => {
|
|
||||||
console.log('wheel')
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{store.state.list
|
|
||||||
.filter((val) => val.type === 'game')
|
|
||||||
.map((item) => (
|
|
||||||
<div class={'flex gap-x-2 items-center'}>
|
|
||||||
<img src={item.icon} alt="game icon" class={'w-[37px] h-[37px] rounded'}></img>
|
|
||||||
<div class={'flex-1 flex flex-col overflow-hidden'}>
|
|
||||||
<span class={'text-white text-[14px]'}>{item.name}</span>
|
|
||||||
<span
|
|
||||||
class={
|
|
||||||
'text-[#fff9] text-[12px] whitespace-nowrap text-ellipsis overflow-hidden'
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{item.des}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class={'w-[49.5%] h-full rounded-xl p-2 relative overflow-hidden'}
|
|
||||||
style={{
|
|
||||||
background: 'rgba(23,33,46,.8)'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{!isWorkBottom.value && (
|
|
||||||
<div
|
|
||||||
class={
|
|
||||||
'w-full absolute bottom-0 left-0 flex justify-center bg-[#17212e] h-[20px] items-center'
|
|
||||||
}
|
|
||||||
onClick={(e) => {
|
|
||||||
e.stopPropagation()
|
|
||||||
e.preventDefault()
|
|
||||||
if (workRef.value) {
|
|
||||||
workRef.value.scrollTop += 20
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<OhVueIcon name={HiChevronDown.name} fill="#ddd"></OhVueIcon>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div
|
|
||||||
ref={workRef}
|
|
||||||
class={clsx('w-full h-full flex flex-col overflow-y-scroll gap-y-2 scrollbar-hide ')}
|
|
||||||
onWheel={() => {
|
|
||||||
console.log('wheel')
|
|
||||||
handleWorkScroll()
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{store.state.list
|
|
||||||
.filter((val) => val.type === 'work')
|
|
||||||
.map((item) => (
|
|
||||||
<div class={'flex gap-x-2 items-center'}>
|
|
||||||
<img src={item.icon} alt="game icon" class={'w-[37px] h-[37px] rounded'}></img>
|
|
||||||
<div class={'flex-1 flex flex-col overflow-hidden'}>
|
|
||||||
<span class={'text-white text-[14px]'}>{item.name}</span>
|
|
||||||
<span
|
|
||||||
class={
|
|
||||||
'text-[#fff9] text-[12px] whitespace-nowrap text-ellipsis overflow-hidden'
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{item.des}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
import { defineComponent } from 'vue'
|
||||||
|
|
||||||
|
export default defineComponent(() => {
|
||||||
|
|
||||||
|
return () => (
|
||||||
|
<div class="w-full h-full bg-[#ecfbff] flex flex-col">
|
||||||
|
middle
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})
|
|
@ -0,0 +1,12 @@
|
||||||
|
import { defineComponent } from 'vue'
|
||||||
|
|
||||||
|
export default defineComponent(() => {
|
||||||
|
return () => (
|
||||||
|
<div
|
||||||
|
class="w-full h-full bg-red-50 flex "
|
||||||
|
style={{
|
||||||
|
background: 'linear-gradient(180deg,#dcefff 0%,#e7ecff 100%)'
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
)
|
||||||
|
})
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { defineComponent } from 'vue'
|
||||||
|
|
||||||
|
export default defineComponent(() => {
|
||||||
|
return () => (
|
||||||
|
<div
|
||||||
|
class="w-full h-full items-center pl-3 gap-x-2 flex py-3 text-white"
|
||||||
|
style={{
|
||||||
|
background: 'linear-gradient(135deg,#5996ff 0%,#4862ff 100%)'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})
|
|
@ -2,12 +2,24 @@ import asyncLoader from '@/utils/asyncLoader'
|
||||||
import type { Widget } from '..'
|
import type { Widget } from '..'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'video',
|
name: 'gameNews',
|
||||||
label: '视频',
|
label: '游戏资讯',
|
||||||
description: '热门视频',
|
description: '游戏资讯',
|
||||||
icon: '/icons/recommendedIcon.png',
|
icon: '/icons/game_news_icon.png',
|
||||||
modal: null,
|
modal: asyncLoader(() => import('./Modal')),
|
||||||
list: [
|
list: [
|
||||||
|
{
|
||||||
|
w: 2,
|
||||||
|
h: 1,
|
||||||
|
label: '小',
|
||||||
|
component: asyncLoader(() => import('./Small'))
|
||||||
|
},
|
||||||
|
{
|
||||||
|
w: 2,
|
||||||
|
h: 2,
|
||||||
|
label: '中',
|
||||||
|
component: asyncLoader(() => import('./Middle'))
|
||||||
|
},
|
||||||
{
|
{
|
||||||
w: 4,
|
w: 4,
|
||||||
h: 2,
|
h: 2,
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
import request from "@/utils/request"
|
|
||||||
import { defineStore } from "pinia"
|
|
||||||
import { reactive } from "vue"
|
|
||||||
type WeApplyType = {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
url: string;
|
|
||||||
icon: string;
|
|
||||||
des: string;
|
|
||||||
type: string;
|
|
||||||
}
|
|
||||||
export const useWeApplyStore = defineStore('weApply', () => {
|
|
||||||
const state = reactive({
|
|
||||||
list: [] as WeApplyType[]
|
|
||||||
})
|
|
||||||
const getWeApplyList = async () => {
|
|
||||||
return request<WeApplyType[]>('GET', '/api/app/weApplys').then(res => {
|
|
||||||
return res
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const getList = async () => {
|
|
||||||
state.list = await getWeApplyList()
|
|
||||||
}
|
|
||||||
getList()
|
|
||||||
return {
|
|
||||||
state,
|
|
||||||
getList
|
|
||||||
}
|
|
||||||
})
|
|
Loading…
Reference in New Issue