具有vue 3 + typescript +组合API的可重用输入组件

gj3fmq9x  于 2022-11-30  发布在  Vue.js
关注(0)|答案(2)|浏览(128)

我有以下(原子)输入组件ElementUI(元素加为vue 3)作为基础组件。
atom/input/index.vue

<template>
  <el-form-item :label="label">
    <ElInput
      :value="modelValue"
      @input="$emit('update:modelValue', handleInputChange($event))"
    >
      <template v-if="prepend" #prepend>Http://</template>
      <template v-if="append" #append>.com</template>
    </ElInput>
  </el-form-item>
</template>
<script setup lang="ts">
  import { ElInput, ElFormItem } from "element-plus"
  interface IInput {
    label: string
    modelValue: any
  }
  const { label, modelValue } = defineProps<IInput>()

  const handleInputChange = (event: Event) => {
    console.log(event)
    return (event.target as HTMLInputElement).value
  }
</script>

在我的主页组件中:
components/home.vue

<template>
  <Input :label="'Book title'" v-model="title" />
<br/>
<h1>{{title}}</h1>
</template>
<script setup lang="ts">
  import { ref } from "vue"
  import Input from "./atom/input/index.vue"
  const title = ref<string>("")
</script>

使用上面的代码设置,组件将以正确的形式显示,并带有其标签。
但是当我开始在输入组件中键入时,我在控制台中得到以下错误。
未捕获(在承诺中)TypeError:无法读取undefined的属性(读取'value')
我还在控制台中记录了该事件,它正在返回我键入的字符。
此外,我还收到以下错误消息:
型别'string'的参数无法指派给型别'Event'的参数。
在我的代码行中:@input="$emit('update:modelValue', handleInputChange($event))"
我能够删除我的类型转换:handleInputChange(<Event | unknown>$event)
我还尝试创建可重用的输入组件与html输入标记相同的值和发射如上所述,它的工作没有任何错误。
有人能帮我弄清楚我错过了什么吗?

更新日期:

根据Duannx的建议,我更改了函数的返回值:

const handleInputChange = (event: any) => {
    return event
  }

但现在,当我在输入字段中键入时,第一个字符将被第二个字符替换,第二个字符将被第三个字符替换,依此类推。
下面是《元素uiPlayground》一期的再现:
演示URL

hmae6n7t

hmae6n7t1#

元素plus input的input事件传递了一个值(string | number),而不是一个Event类型。因此,您可以直接使用$event作为值。

<ElInput
      :value="modelValue"
      @input="$emit('update:modelValue', $event)"
>
      <template v-if="prepend" #prepend>Http://</template>
      <template v-if="append" #append>.com</template>
</ElInput>
4bbkushb

4bbkushb2#

我发现我必须在计算属性中使用set和get方法。

<template>
  <el-form-item :label="label">
    <ElInput
      :autofocus="true"
      :type="type"
      :placeholder="placeholder"
      :show-word-limit="showWordLimit"
      :clearable="clearable"
      :show-password="showPassword"
      :suffix-icon="suffixIcon"
      :prefix-icon="prefixIcon"
      :size="size"
      :max-length="maxLength"
      :value="modelValue"
      @input="$emit('update:modelValue', handleInputChange($event))"
    >
      <template v-if="prepend" #prepend>Http://</template>
      <template v-if="append" #append>.com</template>
    </ElInput>
  </el-form-item>
</template>
<script setup lang="ts">
  import { ElInput, ElFormItem } from "element-plus"
  interface IInput {
    label: string
    type?: string
    placeholder?: string
    maxLength?: number
    showWordLimit?: boolean
    clearable?: boolean
    showPassword?: boolean
    suffixIcon?: any
    prefixIcon?: any
    size?: string
    prepend?: any
    append?: any
    modelValue: any
  }
  const {
    label,
    type,
    placeholder,
    maxLength,
    showWordLimit,
    clearable,
    showPassword,
    suffixIcon,
    prefixIcon,
    size,
    prepend,
    append,
    modelValue,
  } = defineProps<IInput>()

  const handleInputChange = (value: any) => {
    return value
  }

</script>

相关问题