From 5e95a1f7af841f10646133ad0cc155a2c5cea9fd Mon Sep 17 00:00:00 2001 From: syuilo Date: Sun, 26 Jun 2022 03:12:58 +0900 Subject: [PATCH] refactor(client): extract interval logic to a composable function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit あと`onUnmounted`を`onMounted`内で呼んでいたりしたのを修正したりとか --- packages/client/src/components/form/input.vue | 73 ++++++++++--------- packages/client/src/components/form/range.vue | 24 +++--- .../client/src/components/form/select.vue | 57 ++++++++------- .../client/src/components/global/time.vue | 18 ++--- packages/client/src/components/mini-chart.vue | 8 +- .../client/src/components/notification.vue | 17 +++-- .../client/src/components/notifications.vue | 10 ++- packages/client/src/components/poll.vue | 14 ++-- packages/client/src/components/sparkle.vue | 17 +++-- .../src/pages/admin/overview.federation.vue | 13 +--- packages/client/src/scripts/use-interval.ts | 22 ++++++ packages/client/src/widgets/aichan.vue | 31 ++++---- packages/client/src/widgets/calendar.vue | 25 +++---- packages/client/src/widgets/federation.vue | 10 +-- packages/client/src/widgets/online-users.vue | 12 ++- packages/client/src/widgets/rss.vue | 12 ++- packages/client/src/widgets/slideshow.vue | 15 ++-- packages/client/src/widgets/trends.vue | 12 ++- 18 files changed, 207 insertions(+), 183 deletions(-) create mode 100644 packages/client/src/scripts/use-interval.ts diff --git a/packages/client/src/components/form/input.vue b/packages/client/src/components/form/input.vue index 7165671af..5065e2889 100644 --- a/packages/client/src/components/form/input.vue +++ b/packages/client/src/components/form/input.vue @@ -3,7 +3,8 @@
- import { defineComponent, onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs } from 'vue'; -import MkButton from '@/components/ui/button.vue'; import { debounce } from 'throttle-debounce'; +import MkButton from '@/components/ui/button.vue'; +import { useInterval } from '@/scripts/use-interval'; export default defineComponent({ components: { @@ -44,45 +46,45 @@ export default defineComponent({ props: { modelValue: { - required: true + required: true, }, type: { type: String, - required: false + required: false, }, required: { type: Boolean, - required: false + required: false, }, readonly: { type: Boolean, - required: false + required: false, }, disabled: { type: Boolean, - required: false + required: false, }, pattern: { type: String, - required: false + required: false, }, placeholder: { type: String, - required: false + required: false, }, autofocus: { type: Boolean, required: false, - default: false + default: false, }, autocomplete: { - required: false + required: false, }, spellcheck: { - required: false + required: false, }, step: { - required: false + required: false, }, datalist: { type: Array, @@ -91,17 +93,17 @@ export default defineComponent({ inline: { type: Boolean, required: false, - default: false + default: false, }, debounce: { type: Boolean, required: false, - default: false + default: false, }, manualSave: { type: Boolean, required: false, - default: false + default: false, }, }, @@ -134,7 +136,7 @@ export default defineComponent({ const updated = () => { changed.value = false; - if (type?.value === 'number') { + if (type.value === 'number') { context.emit('update:modelValue', parseFloat(v.value)); } else { context.emit('update:modelValue', v.value); @@ -159,30 +161,29 @@ export default defineComponent({ invalid.value = inputEl.value.validity.badInput; }); + // このコンポーネントが作成された時、非表示状態である場合がある + // 非表示状態だと要素の幅などは0になってしまうので、定期的に計算する + useInterval(() => { + if (prefixEl.value) { + if (prefixEl.value.offsetWidth) { + inputEl.value.style.paddingLeft = prefixEl.value.offsetWidth + 'px'; + } + } + if (suffixEl.value) { + if (suffixEl.value.offsetWidth) { + inputEl.value.style.paddingRight = suffixEl.value.offsetWidth + 'px'; + } + } + }, 100, { + immediate: true, + afterMounted: true, + }); + onMounted(() => { nextTick(() => { if (autofocus.value) { focus(); } - - // このコンポーネントが作成された時、非表示状態である場合がある - // 非表示状態だと要素の幅などは0になってしまうので、定期的に計算する - const clock = window.setInterval(() => { - if (prefixEl.value) { - if (prefixEl.value.offsetWidth) { - inputEl.value.style.paddingLeft = prefixEl.value.offsetWidth + 'px'; - } - } - if (suffixEl.value) { - if (suffixEl.value.offsetWidth) { - inputEl.value.style.paddingRight = suffixEl.value.offsetWidth + 'px'; - } - } - }, 100); - - onUnmounted(() => { - window.clearInterval(clock); - }); }); }); diff --git a/packages/client/src/components/form/range.vue b/packages/client/src/components/form/range.vue index 9bf765111..221ad029a 100644 --- a/packages/client/src/components/form/range.vue +++ b/packages/client/src/components/form/range.vue @@ -24,31 +24,31 @@ export default defineComponent({ modelValue: { type: Number, required: false, - default: 0 + default: 0, }, disabled: { type: Boolean, required: false, - default: false + default: false, }, min: { type: Number, required: false, - default: 0 + default: 0, }, max: { type: Number, required: false, - default: 100 + default: 100, }, step: { type: Number, required: false, - default: 1 + default: 1, }, autofocus: { type: Boolean, - required: false + required: false, }, textConverter: { type: Function, @@ -90,14 +90,18 @@ export default defineComponent({ } }; watch([steppedValue, containerEl], calcThumbPosition); + + let ro: ResizeObserver | undefined; + onMounted(() => { - const ro = new ResizeObserver((entries, observer) => { + ro = new ResizeObserver((entries, observer) => { calcThumbPosition(); }); ro.observe(containerEl.value); - onUnmounted(() => { - ro.disconnect(); - }); + }); + + onUnmounted(() => { + if (ro) ro.disconnect(); }); const steps = computed(() => { diff --git a/packages/client/src/components/form/select.vue b/packages/client/src/components/form/select.vue index 87196027a..7f5f8784b 100644 --- a/packages/client/src/components/form/select.vue +++ b/packages/client/src/components/form/select.vue @@ -3,7 +3,8 @@
-