refactor: use defineModel

This commit is contained in:
三咲智子 2023-01-06 23:46:36 +08:00
parent 85ac005570
commit cffcddefb9
No known key found for this signature in database
GPG key ID: 69992F2250DFD93E
9 changed files with 177 additions and 138 deletions

View file

@ -1,14 +1,10 @@
<script lang="ts" setup>
const props = withDefaults(defineProps<{
modelValue?: boolean
}>(), {
modelValue: true,
})
const emit = defineEmits<{
(e: 'update:modelValue', v: boolean): void
(event: 'close'): void
}>()
const visible = useVModel(props, 'modelValue', emit, { passive: true })
const { modelValue: visible } = defineModel<{
modelValue?: boolean
}>()
function close() {
emit('close')

View file

@ -4,8 +4,6 @@ import { Cropper } from 'vue-advanced-cropper'
import 'vue-advanced-cropper/dist/style.css'
export interface Props {
/** Images to be cropped */
modelValue?: File | null
/** Crop frame aspect ratio (width/height), default 1/1 */
stencilAspectRatio?: number
/** The ratio of the longest edge of the cut box to the length of the cut screen, default 0.9, not more than 1 */
@ -16,12 +14,11 @@ const props = withDefaults(defineProps<Props>(), {
stencilSizePercentage: 0.9,
})
const emit = defineEmits<{
(event: 'update:modelValue', value: File): void
const { modelValue: file } = defineModel<{
/** Images to be cropped */
modelValue: File | null
}>()
const vmFile = useVModel(props, 'modelValue', emit, { passive: true })
const cropperDialog = ref(false)
const cropper = ref<InstanceType<typeof Cropper>>()
@ -40,7 +37,7 @@ const stencilSize = ({ boundaries }: { boundaries: Boundaries }) => {
}
}
watch(vmFile, (file, _, onCleanup) => {
watch(file, (file, _, onCleanup) => {
let expired = false
onCleanup(() => expired = true)
@ -59,12 +56,12 @@ watch(vmFile, (file, _, onCleanup) => {
})
const cropImage = () => {
if (cropper.value && vmFile.value) {
if (cropper.value && file.value) {
cropperFlag.value = true
cropperDialog.value = false
const { canvas } = cropper.value.getResult()
canvas?.toBlob((blob) => {
vmFile.value = new File([blob as any], `cropped${vmFile.value?.name}` as string, { type: blob?.type })
file.value = new File([blob as any], `cropped${file.value?.name}` as string, { type: blob?.type })
}, cropperImage.type)
}
}

View file

@ -3,7 +3,6 @@ import { fileOpen } from 'browser-fs-access'
import type { FileWithHandle } from 'browser-fs-access'
const props = withDefaults(defineProps<{
modelValue?: FileWithHandle | null
/** The image src before change */
original?: string
/** Allowed file types */
@ -19,12 +18,13 @@ const props = withDefaults(defineProps<{
allowedFileSize: 1024 * 1024 * 5, // 5 MB
})
const emit = defineEmits<{
(event: 'update:modelValue', value: FileWithHandle): void
(event: 'pick', value: FileWithHandle): void
(event: 'error', code: number, message: string): void
}>()
const file = useVModel(props, 'modelValue', emit, { passive: true })
const { modelValue: file } = defineModel<{
modelValue: FileWithHandle | null
}>()
const { t } = useI18n()

View file

@ -2,9 +2,6 @@
import { useFocusTrap } from '@vueuse/integrations/useFocusTrap'
export interface Props {
/** v-model dislog visibility */
modelValue: boolean
/**
* level of depth
*
@ -48,11 +45,13 @@ const props = withDefaults(defineProps<Props>(), {
const emit = defineEmits<{
/** v-model dialog visibility */
(event: 'update:modelValue', value: boolean): void
(event: 'close',): void
}>()
const visible = useVModel(props, 'modelValue', emit, { passive: true })
const { modelValue: visible } = defineModel<{
/** v-model dislog visibility */
modelValue: boolean
}>()
const deactivated = useDeactivated()
const route = useRoute()

View file

@ -3,19 +3,20 @@ import { SwipeDirection } from '@vueuse/core'
import { useReducedMotion } from '@vueuse/motion'
import type { Attachment } from 'masto'
const props = withDefaults(defineProps<{ media: Attachment[]; threshold?: number; modelValue: number }>(), {
media: [] as any,
threshold: 20,
modelValue: 0,
})
const { media = [], threshold = 20 } = defineProps<{
media?: Attachment[]
threshold?: number
}>()
const emit = defineEmits<{
(e: 'update:modelValue', v: boolean): void
(event: 'close'): void
}>()
const { modelValue } = defineModel<{
modelValue: number
}>()
const target = ref()
const index = useVModel(props, 'modelValue', emit)
const animateTimeout = useTimeout(10)
const reduceMotion = useReducedMotion()
@ -28,15 +29,15 @@ const { isSwiping, lengthX, lengthY, direction } = useSwipe(target, {
passive: false,
onSwipeEnd(e, direction) {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
if (direction === SwipeDirection.RIGHT && Math.abs(distanceX.value) > props.threshold)
index.value = Math.max(0, index.value - 1)
if (direction === SwipeDirection.RIGHT && Math.abs(distanceX.value) > threshold)
modelValue.value = Math.max(0, modelValue.value - 1)
// eslint-disable-next-line @typescript-eslint/no-use-before-define
if (direction === SwipeDirection.LEFT && Math.abs(distanceX.value) > props.threshold)
index.value = Math.min(props.media.length - 1, index.value + 1)
if (direction === SwipeDirection.LEFT && Math.abs(distanceX.value) > threshold)
modelValue.value = Math.min(media.length - 1, modelValue.value + 1)
// eslint-disable-next-line @typescript-eslint/no-use-before-define
if (direction === SwipeDirection.UP && Math.abs(distanceY.value) > props.threshold)
if (direction === SwipeDirection.UP && Math.abs(distanceY.value) > threshold)
emit('close')
},
})
@ -46,9 +47,9 @@ const distanceX = computed(() => {
return 0
if (!isSwiping.value || (direction.value !== SwipeDirection.LEFT && direction.value !== SwipeDirection.RIGHT))
return index.value * 100 * -1
return modelValue.value * 100 * -1
return (lengthX.value / width.value) * 100 * -1 + (index.value * 100) * -1
return (lengthX.value / width.value) * 100 * -1 + (modelValue.value * 100) * -1
})
const distanceY = computed(() => {

View file

@ -38,12 +38,12 @@ const moreMenuVisible = ref(false)
<div i-ri:earth-line />
</NuxtLink>
</template>
<NavBottomMoreMenu v-slot="{ changeShow, show }" v-model="moreMenuVisible" flex flex-row items-center place-content-center h-full flex-1 cursor-pointer>
<NavBottomMoreMenu v-slot="{ toggleVisible, show }" v-model="moreMenuVisible" flex flex-row items-center place-content-center h-full flex-1 cursor-pointer>
<label
flex items-center place-content-center h-full flex-1 class="select-none"
:class="show ? '!text-primary' : ''"
>
<input type="checkbox" z="-1" absolute inset-0 opacity-0 @click="changeShow">
<input type="checkbox" z="-1" absolute inset-0 opacity-0 @click="toggleVisible">
<span v-show="show" i-ri:close-fill />
<span v-show="!show" i-ri:more-fill />
</label>

View file

@ -1,24 +1,20 @@
<script lang="ts" setup>
const props = defineProps<{
modelValue?: boolean
let { modelValue } = $defineModel<{
modelValue: boolean
}>()
const emit = defineEmits<{
(event: 'update:modelValue', value: boolean): void
}>()
const visible = useVModel(props, 'modelValue', emit, { passive: true })
const colorMode = useColorMode()
function changeShow() {
visible.value = !visible.value
function toggleVisible() {
modelValue = !modelValue
}
const buttonEl = ref<HTMLDivElement>()
/** Close the drop-down menu if the mouse click is not on the drop-down menu button when the drop-down menu is opened */
function clickEvent(mouse: MouseEvent) {
if (mouse.target && !buttonEl.value?.children[0].contains(mouse.target as any)) {
if (visible.value) {
if (modelValue) {
document.removeEventListener('click', clickEvent)
visible.value = false
modelValue = false
}
}
}
@ -27,7 +23,7 @@ function toggleDark() {
colorMode.preference = colorMode.value === 'dark' ? 'light' : 'dark'
}
watch(visible, (val) => {
watch($$(modelValue), (val) => {
if (val && typeof document !== 'undefined')
document.addEventListener('click', clickEvent)
})
@ -39,7 +35,7 @@ onBeforeUnmount(() => {
<template>
<div ref="buttonEl" flex items-center static>
<slot :change-show="changeShow" :show="visible" />
<slot :toggle-visible="toggleVisible" :show="modelValue" />
<!-- Drawer -->
<Transition
@ -51,7 +47,7 @@ onBeforeUnmount(() => {
leave-to-class="opacity-0 children:(transform translate-y-full)"
>
<div
v-show="visible"
v-show="modelValue"
absolute inset-x-0 top-auto bottom-full z-20 h-100vh
flex items-end of-y-scroll of-x-hidden scrollbar-hide overscroll-none
bg="black/50"