use define model

This commit is contained in:
2024-05-24 14:53:32 +02:00
parent fff01ff30f
commit 6afce2ef58
6 changed files with 26 additions and 95 deletions

View File

@@ -1,24 +1,11 @@
<script setup lang="ts">
import { vOnClickOutside } from '@vueuse/components';
import { useEventListener, useVModel } from '@vueuse/core';
import { useEventListener } from '@vueuse/core';
import { watch } from 'vue';
interface Props {
open: boolean;
}
const open = defineModel('open', { default: false });
interface Emit {
(e: 'update:open', value: boolean): void;
}
const props = withDefaults(defineProps<Props>(), {
open: false,
});
const emit = defineEmits<Emit>();
const isOpen = useVModel(props, 'open', emit, {passive: true});
watch(isOpen, value => {
watch(open, value => {
if (value) {
document.body.classList.add('overflow-hidden');
} else {
@@ -27,18 +14,18 @@ watch(isOpen, value => {
});
useEventListener('keyup', e => {
if (e.key === 'Escape') {
isOpen.value = false;
open.value = false;
}
});
</script>
<template>
<Transition name="fade">
<template v-if="isOpen">
<template v-if="open">
<div class="fixed inset-0 z-10">
<div class="absolute bg-black opacity-80 inset-0 z-0" />
<div class="absolute grid inset-0">
<div class="justify-self-center m-auto" v-on-click-outside="() => isOpen = false">
<div class="justify-self-center m-auto" v-on-click-outside="() => open = false">
<slot />
</div>
</div>

View File

@@ -1,24 +1,11 @@
<script setup lang="ts">
import { useVModel } from '@vueuse/core';
interface Props {
modelValue?: boolean;
}
interface Emits {
(e: 'update:modelValue', value: boolean): void;
}
const props = withDefaults(defineProps<Props>(), {
modelValue: false
});
const emit = defineEmits<Emits>();
const value = useVModel(props, 'modelValue', emit);
const modelValue = defineModel({ default: false });
</script>
<template>
<label class="flex items-center relative w-max cursor-pointer select-none">
<input type="checkbox" class="appearance-none transition-colors cursor-pointer w-10 h-5 rounded-full checked:bg-emerald-500 peer" v-model="value" />
<input type="checkbox" class="appearance-none transition-colors cursor-pointer w-10 h-5 rounded-full checked:bg-emerald-500 peer" v-model="modelValue" />
<span class="w-5 h-5 right-5 absolute rounded-full transform transition-transform bg-slate-100 peer-checked:bg-emerald-200" />
</label>
</template>

View File

@@ -1,23 +1,10 @@
<script setup lang="ts">
import { vElementHover } from '@vueuse/components';
import { useElementBounding, useVModel } from '@vueuse/core';
import { useElementBounding } from '@vueuse/core';
import { computed, ref } from 'vue';
import { useSharedWindowSize } from './tooltip';
interface Props {
open: boolean;
}
interface Emit {
(e: 'update:open', value: boolean): void;
}
const props = withDefaults(defineProps<Props>(), {
open: false,
});
const emit = defineEmits<Emit>();
const isOpen = useVModel(props, 'open', emit, {passive: true});
const open = defineModel('open', { default: false });
const { width, height } = useSharedWindowSize();
const mainDiv = ref<HTMLDivElement | null>(null);
@@ -39,16 +26,16 @@ const positions = computed(() => {
<template>
<div ref="mainDiv" clas="flex flex-col items-center justify-center" :class="{
'open': isOpen,
'open': open,
'tooltip-top': positions.includes('top'),
'tooltip-bottom': positions.includes('bottom'),
'tooltip-left': positions.includes('left'),
'tooltip-right': positions.includes('right')
}">
<div v-element-hover="(h: boolean) => isOpen = h" class="m-auto header">
<div v-element-hover="(h: boolean) => open = h" class="m-auto header">
<slot name="header" />
</div>
<div v-if="isOpen" class="m-auto">
<div v-if="open" class="m-auto">
<div class="z-10 relative">
<div class="absolute">
<slot />

View File

@@ -1,25 +1,18 @@
<script setup lang="ts">
import { vOnClickOutside } from '@vueuse/components';
import { useVirtualList, useVModel } from '@vueuse/core';
import { useVirtualList } from '@vueuse/core';
import log from 'loglevel';
import { nextTick, ref, watch, watchEffect } from 'vue';
import { MarketType, searchMarketTypes } from './MarketType';
import MarketTypeLabel from "./MarketTypeLabel.vue";
interface Props {
modelValue?: MarketType;
}
interface Emits {
(e: 'update:modelValue', value?: MarketType): void;
(e: 'submit'): void;
}
const props = defineProps<Props>();
const modelValue = defineModel<MarketType>();
const emit = defineEmits<Emits>();
const value = useVModel(props, 'modelValue', emit);
const isOpen = ref(false);
const name = ref('');
const suggestions = ref<MarketType[]>([]);
@@ -47,7 +40,7 @@ const moveUp = () => {
}
const select = (type?: MarketType) => {
log.debug('Select:', type);
value.value = type;
modelValue.value = type;
currentIndex.value = -1;
suggestions.value = [];
isOpen.value = false;
@@ -62,18 +55,18 @@ const submit = async () => {
select(v);
await nextTick();
} else if (props.modelValue === undefined && suggestions.value.length > 0) {
} else if (modelValue.value === undefined && suggestions.value.length > 0) {
select(suggestions.value[0]);
await nextTick();
}
if (value.value === undefined) {
if (modelValue.value === undefined) {
return;
}
emit('submit');
}
watch(() => props.modelValue, async v => {
watch(() => modelValue.value, async v => {
if (v === undefined) {
name.value = '';
} else {
@@ -96,7 +89,7 @@ watchEffect(async () => {
<template>
<div @click="() => isOpen = true" v-on-click-outside="() => isOpen = false">
<div class="fake-input">
<img v-if="value?.id" :src="`https://images.evetech.net/types/${value.id}/icon?size=32`" alt="" />
<img v-if="modelValue?.id" :src="`https://images.evetech.net/types/${modelValue.id}/icon?size=32`" alt="" />
<input type="text" v-model="name" @keyup.enter="submit" @keyup.down="moveDown" @keyup.up="moveUp" />
</div>
<div v-if="suggestions.length > 1" class="z-20 absolute w-96">

View File

@@ -1,24 +1,11 @@
<script setup lang="ts">
import { useVModel } from '@vueuse/core';
interface Props {
modelValue?: boolean;
}
interface Emits {
(e: 'update:modelValue', value: boolean): void;
}
const props = withDefaults(defineProps<Props>(), {
modelValue: false
});
const emit = defineEmits<Emits>();
const value = useVModel(props, 'modelValue', emit);
const modelValue = defineModel({ default: false });
</script>
<template>
<label class="flex items-center relative w-max cursor-pointer select-none">
<input type="checkbox" class="appearance-none transition-colors cursor-pointer w-14 h-7 rounded-full" v-model="value" />
<input type="checkbox" class="appearance-none transition-colors cursor-pointer w-14 h-7 rounded-full" v-model="modelValue" />
<span class="absolute font-medium text-xs right-1"> Buy </span>
<span class="absolute font-medium text-xs right-8"> Sell </span>
<span class="w-7 h-7 right-7 absolute rounded-full transform transition-transform bg-slate-100" />

View File

@@ -1,22 +1,12 @@
<script setup lang="ts">
import { evepraisalAxiosInstance } from '@/market/appraisal/evepraisal';
import { useVModel } from '@vueuse/core';
interface Props {
name: string;
modelValue?: string;
}
interface Emits {
(e: 'update:modelValue', value: string): void;
}
const props = withDefaults(defineProps<Props>(), {
modelValue: ''
});
const emit = defineEmits<Emits>();
const value = useVModel(props, 'modelValue', emit);
const modelValue = defineModel({ default: '' });
defineProps<Props>();
const loadFromId = async (e: Event) => {
const input = e.target as HTMLInputElement;
@@ -31,7 +21,7 @@ const loadFromId = async (e: Event) => {
return;
}
value.value = JSON.stringify(response.data);
modelValue.value = JSON.stringify(response.data);
input.value = '';
}
</script>
@@ -39,6 +29,6 @@ const loadFromId = async (e: Event) => {
<template>
<div class="flex-1 mx-1">
<span>{{ name }}</span><input type="text" class="ms-2" @change="loadFromId" placeholder="id evepraisal" />
<textarea class="mt-1" v-model="value" />
<textarea class="mt-1" v-model="modelValue" />
</div>
</template>