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

View File

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

View File

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