Vue3组件(二)做一个百变input组件

简介: 怎么个百变法呢,就是做一个组件,可以实现 input 的各种形态。

怎么个百变法呢,就是做一个组件,可以实现 input 的各种形态。


原生input的类型



先整理一下 input 的 type 都提供了哪些类型。 原:HTML5之前的类型。 新:HTML5提供的新的类型。


image.png


这里没有写 radio 和 checkbox,因为这两个被我划分为选择类型,同理还有submit。


我们可以依据这个类型定义一个属性:


const type = {
      100: 'textarea', // 多行文本框
      101: 'text', // 单行文本框
      102: 'password', // 密码
      103: 'tel', // 电话
      104: 'email', // 电子邮件
      105: 'url', // url
      106: 'search', // 搜索
      107: 'color', // 颜色
      108: 'text', // 弹窗选择记录
      110: 'date', // 日期
      111: 'datetime-local', // 日期时间
      112: 'time', // 时间
      113: 'week', // 年月
      114: 'month', // 年周
      120: 'number', // 数字
      121: 'range', // 滑块
      130: 'file', // 上传文件
      131: 'file', // 上传图片
      140: 'fulltext', // 富文本编辑器
      150: 'checkbox', // 勾选
      152: 'checkboxs', // 多选组
      153: 'radios', // 单选组
      170: 'select', // 下拉列表框 单选
      171: 'selects', // 列表框 多选
      172: 'selectMore' // 联动下拉列表框
    }
复制代码


具体使用方式下面说。


依据 input 的属性定义一个对象



然后我把可以把input的其他属性整理出来做一个对象:


const meta = reactive({
      controlId: 1000,
      colName: 'companyName',
      controlType: 101,
      isClear: true,
      disabled: false,
      required: true,
      readonly: false,
      pattern: '',
      class: '',
      placeholder: '请输入公司名称',
      title: '公司名称',
      autocomplete: 'on',
      size: 30,
      maxlength: 100,
      optionList: [],
      tdCount: 1
    })
复制代码


准备工作做好了,我们开始做组件。


做一个多功能的文本类控件



模板部分


<template>
  <!---->
  <input :id="'c' + meta.controlId"
    :type="type[meta.controlType]"
    :name="'c' + meta.controlId"
    :value="modelValue"
    :disabled="meta.disabled"
    :readonly="meta.readonly"
    :class="meta.class"
    :placeholder="meta.placeholder"
    :title="meta.title"
    :size="meta.size"
    :maxlength="meta.maxlength"
    :autocomplete="meta.autocomplete"
    :list="meta.optionKey"
    @input="myInput"
    :key="'ckey_'+meta.controlId">
    <!--文本框的备选项-->
    <datalist v-if="typeof(meta.optionKey)!=='undefined'" :id="meta.optionKey">
      <option :key="item.value" v-for="item in meta.optionList" :label="item.title" :value="item.value" />
    </datalist>
</template>
复制代码


这个比较简单,就是把 input 具有的属性都给绑定上。 这里要感谢vue的数据绑定功能,没有设置的属性会自动省略,这就不用我们一个一个判断是不是 undefined 了。


代码部分


export default {
  name: 'nf-h5-form-text',
  props: {
    modelValue: String,
    meta: metaInput
  },
  emits: ['input'],
  setup (props, context) {
    console.log(props)
    // 提交数据
    const myInput = (e) => {
      console.log(e)
      console.log(context)
      context.emit('update:modelValue', e.target.value)
    }
    return {
      type,
      myInput
    }
  }
}
复制代码


这个比较简单了,设计两个属性,一个是 modelValue 绑定 input 的 value 的。 另一个是 meta,后面跟了一个 metaInput ,这个就是上面整理的 input 的属性对象,在组件的属性里面,改成了带验证的形式。


// 定义属性
const metaInput = {
  type: Object,
  default: () => {
    return {
      // 通用
      controlId: Number, // 编号,区别同一个表单里的其他控件
      colName: String, // 字段名称
      controlType: Number, // 用类型编号表示type
      isClear: {
        // isClear  连续添加时是否恢复默认值
        type: Boolean,
        default: false
      },
      defaultValue: String, // 默认值
      autofocus: { // 是否自动获得焦点
        type: Boolean,
        default: false
      },
      disabled: {
        // 是否禁用
        type: Boolean,
        default: false
      },
      required: { // 必填
        type: Boolean,
        default: true
      },
      readonly: { // 只读
        type: Boolean,
        default: false
      },
      pattern: String, // 用正则做验证。
      class: {
        type: String,
        default: 'ant-input ant-input-sm'
      },
      placeholder: String,
      title: String, // 提示信息
      size: Number, // 字符宽度
      maxlength: Number, // 最大字符数
      autocomplete: { // off
        type: String,
        default: 'on'
      },
      optionKey: String, // 备选文字标识
      optionItem: Object // 备选的选项
    }
  }
}
复制代码


这种方式,不仅可以定义组件的属性,而且还能对属性做类型限制、设置默认值等功能。 这样可以让属性设置的更严谨一些。


如果父组件里面设置属性不符合要求,那么浏览器里面会给出来警告提示。


设计目的



为什么要这么设计呢?因为表单里面的元素是各种各样的,比如文本、日期、选择等等,一般需要一个一个写,即是是使用UI库里的form,也还是需要进行具体属性设置。


这个就有点郁闷了,说好的数据绑定呢? 我比较懒,对于这种需要一行一行写的情况比较厌恶,那么能不能简单一点呢,比如使用v-for进行循环?


想要循环,那么就必须规范接口,也就是属性和事件,这两个统一之后我们就可以进行循环了。


如果可以循环的话,那么再大的表单也不用担心了,一个循环搞定。


这里只是处理了一下文本类的控件,后面还要处理选择类的控件,还有其他控件。一路封装下来,最后就可以实现v-for的目的了。



相关文章
|
18天前
|
存储 JavaScript 前端开发
vue3的脚手架模板你真的了解吗?里面有很多值得我们学习的地方!
【10月更文挑战第21天】 vue3的脚手架模板你真的了解吗?里面有很多值得我们学习的地方!
vue3的脚手架模板你真的了解吗?里面有很多值得我们学习的地方!
|
7天前
|
存储 JavaScript 开发者
Vue 组件间通信的最佳实践
本文总结了 Vue.js 中组件间通信的多种方法,包括 props、事件、Vuex 状态管理等,帮助开发者选择最适合项目需求的通信方式,提高开发效率和代码可维护性。
|
7天前
|
存储 JavaScript
Vue 组件间如何通信
Vue组件间通信是指在Vue应用中,不同组件之间传递数据和事件的方法。常用的方式有:props、自定义事件、$emit、$attrs、$refs、provide/inject、Vuex等。掌握这些方法可以实现父子组件、兄弟组件及跨级组件间的高效通信。
|
15天前
|
JavaScript 前端开发 开发者
Vue 3中的Proxy
【10月更文挑战第23天】Vue 3中的`Proxy`为响应式系统带来了更强大、更灵活的功能,解决了Vue 2中响应式系统的一些局限性,同时在性能方面也有一定的提升,为开发者提供了更好的开发体验和性能保障。
35 7
|
16天前
|
前端开发 数据库
芋道框架审批流如何实现(Cloud+Vue3)
芋道框架审批流如何实现(Cloud+Vue3)
38 3
|
15天前
|
JavaScript 数据管理 Java
在 Vue 3 中使用 Proxy 实现数据双向绑定的性能如何?
【10月更文挑战第23天】Vue 3中使用Proxy实现数据双向绑定在多个方面都带来了性能的提升,从更高效的响应式追踪、更好的初始化性能、对数组操作的优化到更优的内存管理等,使得Vue 3在处理复杂的应用场景和大量数据时能够更加高效和稳定地运行。
36 1
|
15天前
|
JavaScript 开发者
在 Vue 3 中使用 Proxy 实现数据的双向绑定
【10月更文挑战第23天】Vue 3利用 `Proxy` 实现了数据的双向绑定,无论是使用内置的指令如 `v-model`,还是通过自定义事件或自定义指令,都能够方便地实现数据与视图之间的双向交互,满足不同场景下的开发需求。
37 1
|
18天前
|
缓存 JavaScript UED
Vue 中实现组件的懒加载
【10月更文挑战第23天】组件的懒加载是 Vue 应用中提高性能的重要手段之一。通过合理运用动态导入、路由配置等方式,可以实现组件的按需加载,减少资源浪费,提高应用的响应速度和用户体验。在实际应用中,需要根据具体情况选择合适的懒加载方式,并结合性能优化的其他措施,以打造更高效、更优质的 Vue 应用。
|
18天前
|
前端开发 JavaScript
简记 Vue3(一)—— setup、ref、reactive、toRefs、toRef
简记 Vue3(一)—— setup、ref、reactive、toRefs、toRef
|
5天前
|
JavaScript 前端开发
如何在 Vue 项目中配置 Tree Shaking?
通过以上针对 Webpack 或 Rollup 的配置方法,就可以在 Vue 项目中有效地启用 Tree Shaking,从而优化项目的打包体积,提高项目的性能和加载速度。在实际配置过程中,需要根据项目的具体情况和需求,对配置进行适当的调整和优化。