代码演示

<template>
  <div class="demo-input">
    <h2>基础用法</h2>
    <Input placeholder="最多输入15字" maxlength="15" />
    <h2>带图标</h2>
    <Input icon="search" placeholder="搜索" />
    <h2>带前后缀</h2>
    <Input inline>
      <template #prepend>$</template>
    </Input>
    <Input inline>
      <template #append>.00</template>
    </Input>
    <Input icon="search" inline>
      <template #prepend>love</template>
      <template #append>.com</template>
    </Input>
    <h2>大号一点</h2>
    <Input size="large" placeholder="最多输入15字" maxlength="15" inline />
    <Input size="large" icon="search" placeholder="搜索" inline />
    <Input size="large" inline>
      <template #prepend>$</template>
    </Input>
    <h2>小号一点</h2>
    <Input size="small" placeholder="最多输入15字" maxlength="15" inline />
    <Input size="small" icon="search" placeholder="搜索" inline />
    <Input size="small" inline>
      <template #prepend>$</template>
    </Input>
    <h2>占满宽度</h2>
    <Input placeholder="请输入文章标题" size="large" block />
    <h2>错误样式</h2>
    <Input placeholder="有问题..." inline hasError />
    <Input icon="search" placeholder="带图标" inline hasError />
    <h2>禁用</h2>
    <Input placeholder="不可编辑" disabled />
    <h2>只读</h2>
    <Input modelValue="只读" readonly />
  </div>
</template>

<script>
export default {
  data() {
    return {};
  },
  methods: {},
  created() {},
};
</script>

<style lang="scss">
.demo-input {
  padding: 10px;
}
</style>
presentation

参数

TIP

This is a tip

参数

Cannot read property 'content' of null

源码

import {
  defineComponent,
  PropType,
  InputHTMLAttributes,
  ref,
  watch,
} from "vue";
import Icon from "../Icon";
import "./index.scss";

const Input = defineComponent({
  name: "Input",
  props: {
    hasError: {
      type: Boolean,
      default: false,
    },
    type: {
      type: String as PropType<InputHTMLAttributes["type"]>,
      default: "text",
    },
    icon: String,
    inline: {
      type: Boolean,
      default: false,
    },
    block: {
      type: Boolean,
      default: false,
    },
    size: {
      type: String as PropType<"small" | "normal" | "large">,
      default: "normal",
    },
    maxlength: [String, Number],
    max: Number,
    min: Number,
    disabled: Boolean,
    readonly: Boolean,
    autofocus: Boolean,
    name: String,
    placeholder: String,
    modelValue: String,
    onFocus: Function as PropType<(e: FocusEvent) => void>,
    onBlur: Function as PropType<(e: FocusEvent) => void>,
    onPressEnter: Function as PropType<(e: KeyboardEvent) => void>,
    onPressCtrlEnter: Function as PropType<(e: KeyboardEvent) => void>,
    onKeypress: Function as PropType<(e: KeyboardEvent) => void>,
    onKeydown: Function as PropType<(e: KeyboardEvent) => void>,
    onKeyup: Function as PropType<(e: KeyboardEvent) => void>,
    onChange: Function as PropType<(e: Event) => void>,
    onInput: Function as PropType<(e: Event) => void>,
  },
  setup(props, { emit, slots }) {
    const value = ref(props.modelValue);

    watch(value, (value) => {
      emit("update:modelValue", value);
    });

    watch(
      () => props.modelValue,
      (newValue) => {
        value.value = newValue;
      }
    );

    const onInput = (e: KeyboardEvent) => {
      value.value = (e.target as HTMLInputElement).value;
      props.onInput?.(e);
    };

    const onKeyup = (e: KeyboardEvent) => {
      props.onKeyup?.(e);
      if (e.key === "Enter" && e.ctrlKey) {
        props.onPressCtrlEnter?.(e);
      } else if (e.key === "Enter") {
        props.onPressEnter?.(e);
      }
    };

    return () => {
      const input = (
        <input
          class="Input"
          type={props.type}
          maxlength={props.maxlength ? +props.maxlength : undefined}
          placeholder={props.placeholder}
          disabled={props.disabled}
          readonly={props.readonly}
          name={props.name}
          autofocus={props.autofocus}
          value={value.value}
          min={props.min}
          max={props.max}
          // @ts-ignore
          onInput={onInput}
          onFocus={props.onFocus}
          onBlur={props.onBlur}
          onKeyup={onKeyup}
          onKeypress={props.onKeypress}
          onKeydown={props.onKeydown}
          onChange={props.onChange}
        />
      );

      return (
        <div
          class={[
            "Input-wrapper",
            {
              "Input-inline": props.inline,
              "Input-block": props.block,
              "Input-large": props.size === "large",
              "Input-small": props.size === "small",
              "has-error": props.hasError,
              "has-icon": !!props.icon,
            },
          ]}
        >
          {slots.prepend ? (
            <div class="Input-addon Input-addon-prepend">
              {slots.prepend()}
            </div>
          ) : null}
          {props.icon ? (
            <div class="Input-icon-wrapper">
              <span class="Input-icon">
                <Icon type={props.icon} />
              </span>
              {input}
            </div>
          ) : (
            input
          )}
          {slots.append ? (
            <div class="Input-addon Input-addon-append">
              {slots.append()}
            </div>
          ) : null}
        </div>
      );
    };
  },
  methods: {
    focus() {
      this.$el.querySelector(".Input")?.focus();
    },
  },
});

export default Input;

最近更新: