基于vue3+ts的el-input组件的二次封装

1. 安装element3版本组件库

# NPM
$ npm install element-plus --save

# Yarn
$ yarn add element-plus

# pnpm
$ pnpm install element-plus

2. 根据文档中的方法引入main.ts

// main.ts
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'

const app = createApp(App)

app.use(ElementPlus)
app.mount('#app')

3.在公共components文件夹中创建 Input文件 和 index.vue文件

        index.vue的封装代码,完成版

<script setup lang="ts">
import { useFormItem } from 'element-plus'

defineOptions({ name: 'FInput' })

// 获取v-model绑定值
const modelValue = defineModel<string>({ local: true })

// 获取传递给自定义组件中的属性值
const attrs = useAttrs()

// 判断是否类型是文本框类型
const isTextarea = computed(() => attrs.type === 'textarea')

// 如果是文本框类型就赋予文本框的默认属性
const textareaProps = computed(() => {
  const showWordLimit = !!attrs.maxlength
  if (isTextarea.value) {
    return {
      autosize: { minRows: 3 },
      showWordLimit: true,
      maxlength: '256',
    }
  }
  return {
    showWordLimit,
  }
})

// 获取组件el-form-item的的label名称,添加在placeholder中
const { form, formItem } = useFormItem()
const placeholder = computed(() => {
  // 查询表单
  if (!form?.model && form?.inline) return '请输入搜索关键词'

  // 文本域
  if (isTextarea.value) return '非必填'

  // 新增or编辑表单
  if (formItem?.label) return `请输入${formItem.label}`

  return '请输入'
})

// 指定从格式化器输入中提取的值
function parser(value: any, ruleNames: string[] | string) {
  ruleNames ??= (attrs.reserve as string[] | string) || ''
  if (typeof ruleNames === 'string') {
    ruleNames = ruleNames.split(',').filter(Boolean)
  }

  const RULES = {
    z: /[\u4E00-\u9FA5]/g, // 中文
    y: /[A-Za-z]/g, // 英文
    s: /[0-9]/g, // 数字
    f: /@_-.,,??()()~`<>《》"“”::|、/g, // 符号
  }

  let result = value
  Object.entries(RULES)
    .filter(([key]) => {
      if (!ruleNames.length) return false
      return !ruleNames.includes(key)
    })
    .forEach(([_, val]) => {
      result = result.replace(val, '')
    })

  return result
}
</script>

<template>
  <el-input
    v-bind="{ ...textareaProps, ...$attrs }"
    v-model="modelValue"
    :placeholder="placeholder"
    clearable
    :formatter="(value:any) => value"
    :parser="parser"
  >
    <template v-for="(_, slotName) in $slots" :key="slotName" #[slotName]="slotProps">
      <slot v-bind="slotProps" :name="slotName" />
    </template>
  </el-input>
</template>

<style lang="scss" scoped></style>

4. 项目中基本使用Input组件

<script setup>

import Input from '@/components/Input/index.vue'

const form = ref({
  bak: '',
  name: '',
})

</script>


   <template>
   <el-form ref="formEl" :model="form" label-width="100">
        <el-form-item prop="rolName" label="名称:">
          <Input v-model="form.name" maxlength="20" placeholder="请输入名称" show-word-limit />
        </el-form-item>
        <el-form-item label="备注:">
          <Input v-model="form.bak" type="textarea" />
        </el-form-item>
      </el-form>
   </template>

使用效果图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值