Replace textControlMixin to vue composition style

This commit is contained in:
timongh 2023-02-08 14:25:16 +08:00
parent d49d7b8909
commit 241ae31d9c
3 changed files with 101 additions and 74 deletions

View File

@ -1,9 +1,9 @@
<template> <template>
<div class="be-text-area" role="text"> <div class="be-text-area" role="text">
<textarea <textarea
ref="input" ref="inputRef"
type="text" type="text"
v-bind="restattrs" v-bind="restAttrs"
:value="text" :value="text"
@change.stop="change" @change.stop="change"
@input.stop="input" @input.stop="input"
@ -14,11 +14,12 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue' import { defineComponent } from 'vue'
import { textControlMixin } from './text-control' import { textControlProps, useTextControl } from './text-control'
export default defineComponent({ export default defineComponent({
name: 'TextArea', name: 'TextArea',
mixins: [textControlMixin], props: textControlProps,
setup: useTextControl,
}) })
</script> </script>
<style lang="scss"> <style lang="scss">

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="be-textbox" role="textbox" :class="{ linear }"> <div class="be-textbox" role="textbox" :class="{ linear }">
<input <input
ref="input" ref="inputRef"
type="text" type="text"
v-bind="restAttrs" v-bind="restAttrs"
:value="text" :value="text"
@ -16,17 +16,19 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue' import { defineComponent } from 'vue'
import { textControlMixin } from './text-control' import { textControlProps, useTextControl } from './text-control'
export default defineComponent({ export default defineComponent({
name: 'TextBox', name: 'TextBox',
mixins: [textControlMixin],
props: { props: {
linear: { linear: {
type: Boolean, type: Boolean,
default: false, default: false,
}, },
...textControlProps,
}, },
emits: ['update:text'],
setup: useTextControl,
}) })
</script> </script>

View File

@ -1,71 +1,95 @@
import { defineComponent } from 'vue' import type { SetupContext, Ref, PropType, ComputedRef } from 'vue'
import type { PropType } from 'vue' import { ref, computed } from 'vue'
export const textControlMixin = defineComponent({ export const textControlProps = {
inheritAttrs: false, text: {
type: String,
required: false,
default: '',
},
changeOnBlur: {
type: Boolean,
required: false,
default: false,
},
validator: {
type: Function as PropType<(value: string, oldValue: string) => string | undefined>,
default: undefined,
},
}
export const useTextControl = (
props: { props: {
text: { text: string
type: String, changeOnBlur: boolean
required: false, validator: (value: string, oldValue: string) => string | undefined
default: '',
},
changeOnBlur: {
type: Boolean,
required: false,
default: false,
},
validator: {
type: Function as PropType<(value: string, oldValue: string) => string>,
default: undefined,
},
}, },
emits: ['update:text'], { emit }: SetupContext<{ 'update:text': (value: string) => boolean }>,
data() { ): {
return { inputRef: Ref<HTMLInputElement | null>
composing: false, composing: Ref<boolean>
restAttrs: lodash.omit( restAttrs: ComputedRef<Record<string, unknown>>
this.$attrs, emitChange: () => void
'onChange', input: () => void
'onInput', change: () => void
'onCompositionstart', compositionStart: () => void
'onCompositionend', compositionEnd: () => void
), focus: () => void
} => {
const inputRef = ref(null) as Ref<HTMLInputElement | null>
const composing = ref(false) as Ref<boolean>
const restAttrs = computed(() =>
lodash.omit(props, 'onChange', 'onInput', 'onCompositionstart', 'onCompositionend'),
)
const emitChange = () => {
let { value } = inputRef.value
if (props.validator) {
value = props.validator(value, props.text)
if (props.changeOnBlur) {
inputRef.value.value = value
}
} }
}, if (value === props.text) {
methods: { return
emitChange() { }
const input = (this.$refs as any).input as { value: any } emit('update:text', value)
let { value } = input }
if (this.validator) {
value = this.validator(value, this.text) const input = () => {
if (this.changeOnBlur) { if (!props.changeOnBlur && !composing.value) {
input.value = value emitChange()
} }
} }
if (value === this.text) {
return const change = () => {
} if (props.changeOnBlur && !composing.value) {
this.$emit('update:text', value) emitChange()
}, }
input() { }
if (!this.changeOnBlur && !this.composing) {
this.emitChange() const compositionStart = () => {
} composing.value = true
}, }
change() {
if (this.changeOnBlur && !this.composing) { const compositionEnd = () => {
this.emitChange() composing.value = false
} input()
}, }
compositionStart() {
this.composing = true const focus = () => {
}, inputRef.value.focus()
compositionEnd() { }
this.composing = false
this.input() return {
}, inputRef,
focus() { composing,
;(this.$refs as any).input.focus() restAttrs,
}, emitChange,
}, input,
}) change,
compositionStart,
compositionEnd,
focus,
}
}