125 lines
4.4 KiB
TypeScript
125 lines
4.4 KiB
TypeScript
import { getImageURL } from '@/utils/images'
|
|
import type { ISkill } from '@/api/info/type'
|
|
import { useVModel } from '@vueuse/core'
|
|
import { UiCheckbox } from '@/components/ui/checkbox'
|
|
import { renderList } from 'vue'
|
|
import './style.scss'
|
|
export default defineComponent({
|
|
name: 'SkillVP',
|
|
props: {
|
|
skills: {
|
|
type: Array as PropType<ISkill[]>,
|
|
default: () => [],
|
|
},
|
|
lvInfo: {
|
|
type: Object as PropType<Record<string, { lv: number; vp: number }>>,
|
|
default: () => ({}),
|
|
},
|
|
},
|
|
emits: ['chooseSkill'],
|
|
setup(props, { emit }) {
|
|
const lvInfo = useVModel(props, 'lvInfo')
|
|
const skills = computed(() =>
|
|
props.skills.filter((a) => a.hasVP && lvInfo).sort((a, b) => a.learnLv - b.learnLv),
|
|
)
|
|
|
|
const currentUsedVP = computed(() => {
|
|
return Object.keys(lvInfo.value)
|
|
.filter((a) => skills.value.find((skill) => skill.id.toString() === a))
|
|
.map((a) => lvInfo.value[a].vp)
|
|
.filter((a) => !!a && a > 0).length
|
|
})
|
|
|
|
const itemChecked = (skillID: string, vp: number) => {
|
|
return computed<boolean>({
|
|
get() {
|
|
if (!lvInfo.value[skillID].vp) {
|
|
lvInfo.value[skillID].vp = 0
|
|
}
|
|
return lvInfo.value[skillID]?.vp == vp
|
|
},
|
|
set(value: boolean) {
|
|
// 选中当前VP形态 并且当前已选VP大于5 并且当前技能没有VP
|
|
if (value && currentUsedVP.value >= 5 && lvInfo.value[skillID]?.vp == 0) {
|
|
return
|
|
}
|
|
if (value) {
|
|
lvInfo.value[skillID].vp = vp
|
|
} else {
|
|
lvInfo.value[skillID].vp = 0
|
|
}
|
|
},
|
|
})
|
|
}
|
|
|
|
return () => (
|
|
<>
|
|
<div class="skill-vp-list">
|
|
{renderList(skills.value, (item) => (
|
|
<div class="vp skill-vp-list__row">
|
|
<div class="skill-vp-list__learn-level">{item.learnLv}</div>
|
|
<div class="skill-vp-list__identity">
|
|
<div class="skill-vp-list__icon-frame">
|
|
<img src={getImageURL(item.icon)} alt={item.name} />
|
|
</div>
|
|
<div class="skill-name">{item.name}</div>
|
|
</div>
|
|
{renderList(2, (index) => (
|
|
<div
|
|
class={['vp-item', index == 1 ? 'vp-item--first' : '']}
|
|
onClick={() => {
|
|
emit('chooseSkill', item.id)
|
|
itemChecked(item.id.toString(), index).value = !itemChecked(
|
|
item.id.toString(),
|
|
index,
|
|
).value
|
|
}}
|
|
>
|
|
{' '}
|
|
<div
|
|
class={[
|
|
'vp-item__content',
|
|
itemChecked(item.id.toString(), index).value ? 'selected' : '',
|
|
]}
|
|
>
|
|
<div class="vp-item__header">
|
|
<div class="vp-item__checkbox">
|
|
<UiCheckbox
|
|
modelValue={itemChecked(item.id.toString(), index).value}
|
|
disabled={
|
|
currentUsedVP.value >= 5 && lvInfo.value[item.id.toString()]?.vp == 0
|
|
}
|
|
/>
|
|
</div>
|
|
<div class="vp-item__icon-frame">
|
|
<div class="vp-item__icon-tint" style="mix-blend-mode: hue;"></div>
|
|
<img
|
|
style="filter:brightness(1) contrast(1) saturate(1.5)"
|
|
class="vp-item__icon"
|
|
src={getImageURL(item.icon)}
|
|
alt={item.name}
|
|
/>
|
|
<div class={`vp_${index} vp-item__badge`}></div>
|
|
</div>
|
|
<div class="vp-item__balance"></div>
|
|
</div>
|
|
<div class="vp-item__name selected-name">{item.vps[index - 1]?.name}</div>
|
|
{renderList(
|
|
item.vps[index - 1]?.desc
|
|
? item.vps[index - 1].desc.replace(/<br\/>/g, '\n').split('\n')
|
|
: [],
|
|
(desc) => (
|
|
<div class="vp-item__description">{desc}</div>
|
|
),
|
|
)}
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
))}
|
|
</div>
|
|
</>
|
|
)
|
|
},
|
|
})
|