完成天气弹框

This commit is contained in:
expdsn 2024-10-15 16:25:01 +08:00
parent 6d9ddcf23b
commit c9cdd4d727
11 changed files with 629 additions and 64 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -9,7 +9,7 @@ const SearchPage = asyncLoader(() => import('@/layout/header/search/SearchPage')
const AdderPage = asyncLoader(() => import('@/layout/adder/AdderPage'))
const BackgroundSwtich = asyncLoader(() => import('@/layout/background/BackgroundSwtich'))
const noFullList: RouteStr[] = ['global-search', 'global-adder', 'global-background']
const fullList: RouteStr[] = []
export default defineComponent(() => {
const router = useRouterStore()
@ -43,37 +43,41 @@ export default defineComponent(() => {
<div
class="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 overflow-hidden transition-all"
style={{
width: full.value ? '100%' : '900px',
height: full.value ? '100vh' : '540px',
width: full.value ? '100%' : '984px',
height: full.value ? '100vh' : '580px',
borderRadius: full.value ? '0' : '1rem'
}}
>
{/* 关闭按钮 */}
<div
class={
'w-5 h-5 flex justify-center items-center rounded-full overflow-hidden absolute bg-red-500/70 hover:bg-red-500 transition-all cursor-pointer z-30 ' +
(router.path === 'global-adder' ? 'top-6 right-4' : 'top-2 right-2')
'w-[16px] h-[16px] group flex justify-center items-center rounded-full overflow-hidden absolute bg-red-500/70 hover:bg-red-500 transition-all cursor-pointer z-30 ' +
(router.path === 'global-adder' ? 'top-6 right-8' : 'top-2 right-6')
}
onClick={() => {
router.back()
}}
>
<OhVueIcon name="md-close" scale={0.7} fill="white" />
<div class={' items-center justify-center hidden group-hover:flex'}>
<OhVueIcon name="md-close" scale={0.6} fill="white" />
</div>
</div>
{/* 全屏按钮 */}
{noFullList.includes(router.path) ? null : (
{!fullList.includes(router.path) ? null : (
<div
class="w-5 h-5 flex justify-center items-center rounded-full overflow-hidden absolute top-2 right-10 bg-green-500/70 hover:bg-green-500 transition-all cursor-pointer z-30"
class="w-[16px] group h-[16px] flex justify-center items-center rounded-full overflow-hidden absolute top-2 right-12 bg-green-500/70 hover:bg-green-500 transition-all cursor-pointer z-30"
onClick={() => {
full.value = !full.value
}}
>
<div class={' items-center justify-center hidden group-hover:flex'}>
<OhVueIcon
name={full.value ? 'md-closefullscreen' : 'md-openinfull'}
scale={0.6}
fill="white"
/>
</div>
</div>
)}
<div class="w-full h-full flex justify-center items-center">
@ -84,8 +88,7 @@ export default defineComponent(() => {
<AdderPage />
) : router.path === 'global-background' ? (
<BackgroundSwtich />
) :
router.path.startsWith('widget-') ? (
) : router.path.startsWith('widget-') ? (
(() => {
const name = router.path.split('-')[1]
const selected = widgetList.find((el) => el.name === name)

View File

@ -3,28 +3,29 @@
@tailwind utilities;
:root {
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
font-family:
SourceHanSans,
SourceHanSansCN-Regular,
-apple-system,
BlinkMacSystemFont,
Helvetica Neue,
PingFang SC,
Microsoft YaHei,
Source Han Sans SC,
Noto Sans CJK SC,
WenQuanYi Micro Hei,
sans-serif;
WenQuanYi Micro Hei !important;
}
@font-face {
font-family: 'SourceHanSans';
font-family: 'SourceHanSansCN-Regular';
src: url('/fonts/SourceHanSansCN-Regular.subset.otf') format('truetype');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'SourceHanSansCN-bold';
src: url('/fonts/SourceHanSansCN-Regular.subset.otf') format('truetype');
font-weight: 700;
font-style: normal;
}
body {
/* ! 全局禁用鼠标选择,需要在其他位置放开 */
user-select: none;

View File

@ -8,12 +8,14 @@ import getFp from './utils/getFp'
import vOutsideClick from './utils/vOutsideClick'
import dayjs from 'dayjs'
import Toast, { useToast, type PluginOptions } from 'vue-toastification'
import customParseFormat from 'dayjs/plugin/customParseFormat'
import 'vue-toastification/dist/index.css'
import 'dayjs/locale/zh-cn'
dayjs.locale('zh-cn')
const app = createApp(App)
export const globalToast = useToast()
dayjs.extend(customParseFormat)
// ! persist 利用 localstorage请不要在大量数据时使用
// 大量数据(扩张内容,文件),清直接使用 ./db.ts

View File

@ -19,7 +19,7 @@ export default defineStore(
showTime: true,
showAdder: true,
// 尺寸
blockSize: 6,
blockSize: 6.7,
blockPadding: 1,
mainWidth: 70,
blockRadius: 0.2,

View File

@ -1,10 +1,69 @@
import { defineComponent } from 'vue'
import useWeatherStore from './useWeatherStore'
import WeatherIcon from './weatherIcon'
import dayjs from 'dayjs'
import clsx from 'clsx'
export default defineComponent(() => {
const weather = useWeatherStore()
return () => <div class="w-full h-full bg-red-50"
return () => (
<div class="w-full h-full bg-[#ecfbff] flex flex-col">
<div class={'z-10 relative flex justify-evenly px-3 py-3 items-center text-white'}>
<span class="text-[26px] font-din font-bold">{weather.weatherData?.base.stemp}°</span>
<div class="flex flex-col justify-between items-center h-full">
<div class="flex items-center gap-x-1">
<span class="font-bold text-[14px] leading-[14px] ">
{weather.weatherData?.city.name}
</span>
</div>
<span class="text-[12px] bg-white/[.2] rounded-xl px-4 py-[2px] font-din font-bold">
{weather.weatherData?.base.ltemp}°/{weather.weatherData?.base.htemp}°
</span>
</div>
<div class={'flex flex-col justify-center items-center'}>
<WeatherIcon size={30} weather={weather.weatherData?.base.weather}></WeatherIcon>
<span class="text-[12px]">{weather.weatherData?.base.weather}</span>
</div>
</div>
<div class="flex-1 ">
<div class="w-full h-full flex justify-evenly items-end pb-[6px]">
{weather.weatherData?.weathers7.map((item, idx) => {
return (
<div
class={clsx(
'flex flex-col items-center justify-center gap-y-[2px] py-[14px] px-[3px] rounded-[15px] ',
idx === 0 ? 'text-white' : 'text-[#333]'
)}
style={{
background: 'linear-gradient(135deg,#5996ff 0%,#4862ff 100%)'
}}>{}</div>
backgroundImage:
idx === 0
? 'linear-gradient(135deg,#5996ff,#4862ff)'
: 'linear-gradient(135deg, rgba(89, 150, 255, .1), #4862ff1a)'
}}
>
<span class="text-[12px]">
{idx === 0
? '今天'
: idx === 1
? '明天'
: dayjs(item.date, 'MM月DD日').format('ddd')}
</span>
<WeatherIcon size={20} weather={item.weather}></WeatherIcon>
<span class="text-[12px] font-bold font-din ">
{item.ltemp + '°/' + item.htemp + '°'}
</span>
</div>
)
})}
</div>
</div>
<div
class={'w-full h-[100px] absolute left-0 top-0 '}
style={{
backgroundImage: `url('/weather_img/img/weather_bg_large.webp')`,
backgroundRepeat: 'no-repeat',
backgroundSize: 'contain'
}}
></div>
</div>
)
})

View File

@ -1,33 +1,67 @@
import { defineComponent } from 'vue'
import useWeatherStore from './useWeatherStore'
import WeatherIcon from './weatherIcon'
import dayjs from 'dayjs'
import clsx from 'clsx'
export default defineComponent(() => {
const weather = useWeatherStore()
return () => (
<div class="w-full h-full bg-[#ecfbff] ">
<div class="w-full h-full bg-[#ecfbff] flex flex-col">
<div class={'z-10 relative flex justify-between px-3 py-3 items-center text-white'}>
<span class="text-[26px] font-din font-bold">{weather.weatherData?.base.stemp}°</span>
<div class="flex flex-col gap-y-[1px]">
<div class="flex flex-col justify-between items-center h-full">
<div class="flex items-center gap-x-1">
<span class="font-bold text-[14px] leading-[14px] ">
{weather.weatherData?.city.name}
</span>
</div>
<span class={'tracking-tight flex gap-x-1 items-center'}>
<span class="text-[12px]">
<span class="text-[12px] bg-white/[.2] rounded-xl px-2 py-[2px] font-din font-bold">
{weather.weatherData?.base.ltemp}°/{weather.weatherData?.base.htemp}°
</span>
</span>
</div>
<div class={'flex flex-col justify-center items-center'}>
<WeatherIcon size={30} weather={weather.weatherData?.base.weather}></WeatherIcon>
<span class="text-[12px]">{weather.weatherData?.base.weather}</span>
</div>
</div>
<div class="flex-1 ">
<div class="w-full h-full flex justify-evenly items-end pb-[6px]">
{weather.weatherData?.weathers7
.filter((_, idx) => idx < 3)
.map((item, idx) => {
return (
<div
class={'w-full h-[73px] absolute left-0 top-0 '}
class={clsx(
'flex flex-col items-center justify-center gap-y-[2px] py-[14px] px-[3px] rounded-[15px] ',
idx === 0 ? 'text-white' : 'text-[#333]'
)}
style={{
backgroundImage:
idx === 0
? 'linear-gradient(135deg,#5996ff,#4862ff)'
: 'linear-gradient(135deg, rgba(89, 150, 255, .1), #4862ff1a)'
}}
>
<span class="text-[12px]">
{idx === 0 ? '今天' : idx === 1 ? '明天' : dayjs().format('ddd')}
</span>
<WeatherIcon size={20} weather={item.weather}></WeatherIcon>
<span class="text-[12px] font-bold font-din ">
{item.ltemp + '°/' + item.htemp + '°'}
</span>
</div>
)
})}
</div>
</div>
<div
class={'w-full h-[100px] absolute left-0 top-0 '}
style={{
backgroundImage: `url('/weather_img/img/weather_bg_mdeium.webp')`,
backgroundRepeat: 'no-repeat',
backgroundSize: '100%'
backgroundSize: 'contain'
}}
></div>
</div>

View File

@ -1,5 +1,333 @@
import { defineComponent } from 'vue'
import { Cascader, message } from 'ant-design-vue'
import { computed, defineComponent, onMounted, ref, type HTMLAttributes, type VNodeRef } from 'vue'
import useWeatherStore from './useWeatherStore'
import type { DefaultOptionType } from 'ant-design-vue/es/select'
import { addIcons, OhVueIcon } from 'oh-vue-icons'
import clsx from 'clsx'
import { FaMinus, HiSolidLocationMarker } from 'oh-vue-icons/icons'
import WeatherIcon from './weatherIcon'
import dayjs from 'dayjs'
addIcons(FaMinus, HiSolidLocationMarker)
export default defineComponent(() => {
return () => <div class="w-full h-full bg-red-50"></div>
const store = useWeatherStore()
const hourRef = ref<VNodeRef | null>(null)
const cascaderTriiger = ref(true)
const searchValue = ref('')
const filter = (inputValue: string, path: DefaultOptionType[]) =>
path.some(
(option) => (option.label as string).toLowerCase().indexOf(inputValue.toLowerCase()) > -1
)
onMounted(() => {
store.queryAll()
})
const nowWeather = computed(() => {
if (store.state.selectedCityCode === -1) return store.weatherData
const idx = store.state.weatherList.findIndex((val) => val.id === store.state.selectedCityCode)
if (idx !== -1) {
return store.state.weatherList[idx].data
} else {
return store.weatherData
}
})
function getPracticeIndex(val: string) {
const numVal = parseFloat(val) || 0
if (numVal < 115) {
return '适宜晨练'
} else {
return '不宜晨练'
}
}
function pollution(val: string) {
const numVal = parseFloat(val) || 0
if (numVal < 35) {
return '优'
} else if (numVal < 75) {
return '良'
} else if (numVal < 115) {
return '轻度污染'
} else if (numVal < 150) {
return '中度污染'
} else if (numVal < 250) {
return '重度污染'
} else if (numVal >= 250) {
return '严重污染'
} else {
return '未知'
}
}
function shirtIndex(val: string) {
const numVal = parseFloat(val) || 0
if (numVal < 6) {
return '寒冷'
} else if (numVal < 10.9) {
return '冷'
} else if (numVal < 14.9) {
return '凉'
} else if (numVal < 17.9) {
return '温凉'
} else if (numVal < 20.9) {
return '凉舒适'
} else if (numVal < 23.9) {
return '舒适'
} else if (numVal < 27.9) {
return '热舒适'
} else if (numVal >= 28) {
return '炎热'
} else {
return '温凉'
}
}
function coldIndex(val: string) {
const numVal = parseFloat(val) || 0
if (numVal < 6) {
return '易发感冒'
} else if (numVal < 10.9) {
return '较易发感冒'
} else {
return '不易发感冒'
}
}
return () => (
<div
class="w-full h-full bg-red-50 flex "
style={{
background: 'linear-gradient(180deg,#dcefff 0%,#e7ecff 100%)'
}}
>
<div class={' w-[228px] px-6 pt-6 h-full bg-white/[.7] rounded-[20px]'}>
<div class={'relative '}>
{cascaderTriiger.value && (
<Cascader
class={'w-full shadow-sm rounded-lg border-[1px] '}
options={store.state.cityOptions}
onChange={async (e: any, option: DefaultOptionType[]) => {
cascaderTriiger.value = false
setTimeout(() => {
cascaderTriiger.value = true
}, 0)
if (store.state.weatherList.findIndex((val) => val.id === option[2].value) !== -1) {
message.info('该地区已添加')
return
}
if (store.state.weatherList.length >= 5) {
message.info('最多只能添加5个地区')
return
}
store.state.weatherList.push({
id: option[2].value as number,
name: option[2].label,
data: await store.query(option[2].value as number)
})
store.state.selectedCityCode = option[2].value as number
}}
notFoundContent="没有找到该地区"
onClick={() => {
if (store.state.cityOptions.length === 0) store.queryCity()
}}
searchValue={searchValue.value}
placeholder="搜索其他地区天气"
showSearch={{ filter }}
onSearch={(value) => {
searchValue.value = value
}}
/>
)}
</div>
<div class={'w-full flex flex-col gap-y-2 mt-4'}>
<div
onClick={() => {
store.state.selectedCityCode = -1
}}
class={clsx(
'flex flex-col justify-between gap-x-4 w-full h-[60px] relative py-2 px-3 rounded-lg cursor-pointer hover:bg-gradient-to-b from-[#d6ecff] to-[#dce3ff]',
store.state.selectedCityCode === -1
? 'bg-gradient-to-b from-[#d6ecff] to-[#dce3ff]'
: 'bg-black/[0.05]'
)}
>
<div class={'flex items-center justify-between gap-x-1 text-[#333]'}>
<div class={'flex items-center gap-x-1 flex-1'}>
<OhVueIcon name={HiSolidLocationMarker.name} fill="#333" scale={0.8}></OhVueIcon>
<span class={'text-[14px]'}>{store.weatherData?.city.name}</span>
</div>
<span class={'font-bold text-[16px]'}>{store.weatherData?.base.stemp}°</span>
</div>
<div class={'flex items-center justify-between gap-x-1 text-[#333]'}>
<div class={'flex items-center text-[12px] gap-x-1 '}>
<WeatherIcon weather={store.weatherData?.base.weather} size={16}></WeatherIcon>
<span>{store.weatherData?.base.weather}</span>
</div>
<span class={'text-[12px]'}>
{store.weatherData?.base.ltemp}°/{store.weatherData?.base.htemp}°
</span>
</div>
</div>
{store.state.weatherList.map((item) => (
<div
onClick={() => {
store.state.selectedCityCode = item.id
}}
class={clsx(
'flex flex-col group justify-between gap-x-4 w-full h-[65px] group relative py-2 px-3 rounded-lg cursor-pointer hover:bg-gradient-to-b from-[#d6ecff] to-[#dce3ff]',
store.state.selectedCityCode === item.id
? 'bg-gradient-to-b from-[#d6ecff] to-[#dce3ff]'
: 'bg-black/[0.05]'
)}
key={item.id}
>
<div class={'flex items-center justify-between gap-x-1 text-[#333]'}>
<div class={'flex items-center gap-x-1 flex-1'}>
<span class={'text-[14px]'}>{item.data?.city.name}</span>
</div>
<span class={'font-bold text-[16px]'}>{item.data?.base.stemp}°</span>
</div>
<div class={'flex items-center justify-between gap-x-1 text-[#333]'}>
<div class={'flex items-center text-[12px] gap-x-1 '}>
<WeatherIcon weather={item.data?.base.weather} size={16}></WeatherIcon>
<span>{item.data?.base.weather}</span>
</div>
<span class={'text-[12px]'}>
{item.data?.base.ltemp}°/{item.data?.base.htemp}°
</span>
</div>
<div
class={
'absolute hidden top-[-6px] z-10 right-[-6px] group-hover:flex bg-black/20 cursor-default rounded-full h-[20px] w-[20px] items-center justify-center'
}
onClick={(e) => {
e.stopPropagation()
store.state.weatherList = store.state.weatherList.filter(
(val) => val.id !== item.id
)
store.state.selectedCityCode = -1
}}
>
<div class={'w-[70%] h-[2px] bg-white/80 rounded-sm'}></div>
</div>
</div>
))}
</div>
</div>
<div class={'flex-1 w-0'}>
<div class={'w-full h-full px-7 py-4 flex flex-col gap-y-3'}>
<div class="flex">
<div class={'flex flex-col text-[#333]'}>
<span class="text-[#666]">{store.weatherData?.city.name}</span>
<span class={'text-[57px] font-bold'}>{nowWeather.value?.base.stemp}°</span>
<span class="text-[14px] flex gap-x-1">
{nowWeather.value?.base.weather}
<span>
{nowWeather.value?.base.ltemp}°/{nowWeather.value?.base.htemp}°
</span>
<WeatherIcon weather={nowWeather.value?.base.weather} size={20}></WeatherIcon>
</span>
<span class={'text-[14px] text-[#666]'}>
{nowWeather.value?.base.WD} {nowWeather.value?.base.WS}
</span>
</div>
<div class={'flex-1 flex items-center justify-center'}>
<div class={'grid grid-cols-3 grid-rows-2 text-[#666] text-[12px] gap-x-3 gap-y-2'}>
<div class="flex gap-x-1">
<span>:</span>
<span>{getPracticeIndex(nowWeather.value?.base.aqi || '0')}</span>
</div>
<div class="flex gap-x-1">
<span>:</span>
<span>{pollution(nowWeather.value?.base.pm25 || '0')}</span>
</div>
<div class="flex gap-x-1">
<span>穿:</span>
<span>{shirtIndex(nowWeather.value?.base.stemp || '0')}</span>
</div>
<div class="flex gap-x-1">
<span>:</span>
<span>
{nowWeather.value?.hour24.some((val) => val.weather.includes('雨'))
? '需带伞'
: '无需带伞'}
</span>
</div>
<div class="flex gap-x-1">
<span>:</span>
<span>{coldIndex(nowWeather.value?.base.stemp || '0')}</span>
</div>{' '}
<div class="flex gap-x-1">
<span>线:</span>
<span>线{nowWeather.value?.base.ultraviolet}</span>
</div>
</div>
</div>
</div>
<div class={'w-full bg-white/60 rounded-xl py-2 px-3 '}>
<span class={'text-[#999] text-[14px]'}>24</span>
<div
ref={hourRef}
class="flex w-full flex-grow-0 overflow-x-scroll gap-x-2 mt-1 scrollbar-hide"
onWheel={(e) => {
e.preventDefault()
if (!hourRef.value) return
hourRef.value.scrollLeft += e.deltaY
}}
>
{nowWeather.value?.hour24.map((item, idx) => (
<div
class={clsx(
'flex flex-col shrink-0 items-center w-[60px] text-[#333] rounded-lg py-4 justify-center gap-y-3',
idx === 0 ? 'bg-black/[.05]' : 'hover:bg-black/[0.05]'
)}
key={item.hour}
>
<WeatherIcon weather={item.weather} size={20}></WeatherIcon>
<span>{item.stemp}°</span>
<span>{idx === 0 ? '现在' : item.hour + '时'}</span>
</div>
))}
</div>
</div>
<div class={'flex-1 h-0 w-full'}>
<div class={' h-full w-full bg-slate-50/[.7] rounded-xl py-2 px-3 flex flex-col'}>
<span class={'text-[#999] text-[14px]'}>7</span>
<div class="w-full grid grid-cols-7 gap-x-2 grid-rows-1 flex-1 items-end pb-[6px] mt-1">
{nowWeather.value?.weathers7.map((item, idx) => {
return (
<div
class={clsx(
'flex flex-col items-center justify-between gap-y-[2px] text-[#333] text-[14px] h-full py-[14px] px-[3px] rounded-[15px] ',
idx === 0 ? 'bg-black/[0.05]' : 'hover:bg-black/[0.05]'
)}
>
<span class=" font-bold font-din ">
{item.ltemp + '°/' + item.htemp + '°'}
</span>
<div class={'flex flex-col gap-y-1 justify-center items-center'}>
<WeatherIcon size={20} weather={item.weather}></WeatherIcon>
<span class={'text-[14px]'}>{item.weather}</span>
</div>
<div class={'flex flex-col items-center justify-center text-[12px] '}>
<span class={'text-[#999]'}>
{dayjs(item.date, 'MM月DD日').format('MM/DD')}
</span>
<span class={'text-[14px]'}>
{idx === 0
? '今天'
: idx === 1
? '明天'
: dayjs(item.date, 'MM月DD日').format('ddd')}
</span>
</div>
</div>
)
})}
</div>
</div>
</div>
</div>
</div>
</div>
)
})

View File

@ -1,5 +1,6 @@
import { defineComponent } from 'vue'
import useWeatherStore from './useWeatherStore'
import WeatherIcon from './weatherIcon'
export default defineComponent(() => {
const weather = useWeatherStore()
@ -15,6 +16,7 @@ export default defineComponent(() => {
<div class="flex flex-col gap-y-[1px]">
<div class="flex items-center gap-x-1">
<span class="font-bold text-[14px] leading-[14px]">{weather.weatherData?.city.name}</span>
<WeatherIcon size={16} weather={weather.weatherData?.base.weather}></WeatherIcon>
</div>
<span class={'tracking-tight flex gap-x-1 items-center'}>
<span class="text-[12px]">{weather.weatherData?.base.weather}</span>

View File

@ -19,6 +19,7 @@ type WeatherState = {
selected: number
selectedCityCode: number
cityOptions: AntdCityOptions[]
weatherList: { id: number; data?: WeatherData; name: '' }[]
}
const baseWeatherUrl = 'https://i.tianqi.com/'
@ -27,7 +28,8 @@ export default defineStore('weather', () => {
const state = reactive({
selected: 0,
selectedCityCode: -1,
cityOptions: []
cityOptions: [],
weatherList: []
} as WeatherState)
const city = ref('')
@ -53,18 +55,40 @@ export default defineStore('weather', () => {
}
const fetchWeather = async (code: number) => {
try {
const nowResponse = await fetch(baseWeatherUrl + '?c=mfjson' + (code ? '&id=' + code : ''))
const nowResponse = await fetch(baseWeatherUrl + '?c=mfjson' + (code !== -1 ? '&id=' + code : ''))
const res = await nowResponse.json()
weatherData.value = res
return res
} catch (e) {
return
}
}
const queryAll = () => {
state.weatherList.forEach(async item => {
item.data = await fetchWeather(item.id)
})
}
const query = async (code: number) => {
const data = await fetchWeather(code)
return data
}
watch(
() => state.selectedCityCode,
(e) => {
fetchWeather(e)
async (e) => {
if (e === -1) {
const data = await fetchWeather(e)
weatherData.value = data
} else {
const idx = state.weatherList.findIndex((item) => item.id === e)
if (idx === -1) {
if (!state.weatherList[idx]?.data) return
const data = await fetchWeather(e)
state.weatherList[idx].data = data
}
}
},
{
immediate: true
@ -75,7 +99,9 @@ export default defineStore('weather', () => {
state,
city,
weatherData,
queryCity
queryCity,
queryAll,
query
}
}, {
persist: true

View File

@ -0,0 +1,110 @@
import { computed, defineComponent, render } from 'vue'
export default defineComponent({
name: 'WeatherIcon',
props: {
weather: {
type: String,
default: ''
},
size: {
type: Number,
default: 24
}
},
setup: (props, ctx) => {
const list = [
'阴', //0
'大雪', //1
'暴雪', //2
'中雪', //3
'小雪', //4
'雨夹雪', // 5
'阵雪', //6
'雪', //7
'中雨', //8
'小阵雨',
'雷阵雨伴有冰雹', // 10
'阵雨',
'冻雨',
'雷阵雨',
'大雨',
'暴雨', // 15
'大暴雨',
'特大暴雨',
'夜间小雨',
'小雨',
'晴转小雨', // 20
'多云转晴',
'睛转多云',
'多云',
'大部份多云',
'打雷', // 25
'冷',
'霜',
'强沙尘暴',
'沙尘暴',
'龙卷风', // 30
'杨沙',
'雾',
'晴',
'霾',
'风', // 35
'大风',
'飓风',
'未知天气', //38
'多云转阴',
'晴转多云', //40
'阴转小雨',
'多云转阴',
'轻度雾霾', //43
'轻度雾霾转多云', //44
'小雨转多云', //45
'小雨转晴',
'阴转晴',
'中度雾霾', //48
'阴转多云',
'阴到小雨', //50
'晴转雪 ',
'多云转雨',
'风转晴',
'多云转小雪',
'雪转雨', //55
'小雨转雨',
'多云转雪',
'小雪转多云',
'晴转阴',
'阴转中雨', //60
'雪转多云',
'小雨转阴', //62
'小雨转中雨',
'多云转小雨',
'小雨到大雨', //65
'轻度雾霾转小雨',
'轻度雾霾转晴',
'小雨转雪',
'阴转雨', //69
'中雨转阴', //70
'中雨转小雨', //71
'大雨转小雨' //72
]
const idx = computed(() => list.indexOf(props.weather || '未知天气'))
const url = computed(() => {
return idx.value < 0 ? '/weather_img/38.png' : `/weather_img/${idx.value}.png`
})
return () => (
<>
<img
style={{
width: `${props.size}px`,
height: `${props.size}px`
}}
class={' object-contain'}
src={url.value}
alt="weather icon"
></img>
</>
)
}
})