当前位置: 首页 > news >正文

前端组件库造轮子——Input组件开发教程

前端组件库造轮子——Input组件开发教程

前言

本系列旨在记录前端组件库开发经验,我们的组件库项目目前已在Github开源,下面是项目的部分组件。文章会详细介绍一些造组件库轮子的技巧并且最后会给出完整的演示demo。

image.png

文章旨在总结经验,开源分享,有问题的话也希望路过的大佬指正。

组件开发流程

核心功能

Input组件的核心功能其实就是实现v-model,我们需要对封装出来的组件让他也拥有v-model的功能。

比如举个例子:

在vue中,我们可以直接对input标签使用v-model,但是我们没办法对封装的组件直接来使用v-model

// input 标签可以使用
<input type="text" v-model="input" />// 自定义封装的 Input 组件 不可以使用v-model
<Input v-model="input" placeholder="请输入内容"></Input>

实现v-model

实现v-model其实就是双向绑定,比如我们可以利用vue提供的语法糖v-bind和事件调用来实现

<input v-bind:value="value" v-on:input="value= $event.target.value" />

所以,原理其实是一样的,在vue中,暴露给我们一组交互的数据

props: modelValue
emit: update:modelValue

其实就是在使用v-model时,在子组件中会用props: modelValue来接受传进来的数据,同时利用事件emit: update:modelValue 官方资料

具体实现代码就是

<template><inputclass="input"type="text":value="text"@input.stop="handerInput" />
</template>
<script setup lang="ts">
import { ref, watch } from "vue";
const props = defineProps({modelValue: {type: String,default: "",},
});
const emit = defineEmits(["update:modelValue"]);
const handerInput = (e: Event) => {const target = e.target as HTMLInputElement;emit("update:modelValue", target.value);text.value = target.value;
};
</script>

这样我们就实现完成input组件的双向绑定功能。

但是还没完,我们还需要来监听数据的修改,来更新:value:text绑定的值。

为什么要做这一步呢?

我们在刚刚其实只是实现了改变input中的值,会修改我们v-model绑定的值,但是并没有实现了v-model修改,来改变input的值。

看下面这个例子

比如,我们用两个input同时绑定上同一个value值,当我修改了一个input的值同时,另一个input的值一个也同步修改才对。

jcode

因此,我们还需要监听modelValue的值,同步修改text.value

watch(() => props.modelValue,(newVal) => {if (newVal == "") return (text.value = "");text.value = props.modelValue ? props.modelValue : "";},
);

这样我们才算完成了这个核心功能

样式更替

在组件库开发中,我们会发现一个组件他是有多种样式可以选择的

image.png

例如在Hview-ui中,input组件就存在可以用size更换大小的样式,像这种样式开发在组件库开发中也是非常常见。

具体实现也是非常容易,我们需要在props预留出我们想要的属性,比如size,当然样式也得预先设置好,这里就不多赘述了,想比对大家来说都不是问题。

size: {type: String,default: "medium",
},

接下来样式更替在组件中的常用写法,这个写法就会把当前props.size的值渲染出来,放回成一个class类,接下来我们直接在template加上这个类即可。

// template
<template><inputclass="input"type="text":value="text":class="size"  // 在这里加上size类@input.stop="handerInput" />
</template>// script
const size = computed(() => {return {[`h-input-${props.size}`]: props.size,};
});

这样当 props.size 的值为 small 时,对象会被渲染成这样,在:class中,如果:后面为true那么就是加上h-input-small这个类了。

{ 'h-input-small': 'small' 
}

attrs

最后介绍一下attrs属性,想必大家平时应该不怎么会用到这个属性,但是这个属性在开发组件时相当好用,这个attrs属性可以把style,props等属性拦截下来,把其它属性渗透给孩子组件。

举个例子就明白了,

input标签中自带着placeholder,type等属性,如果我们要开发Input组件的话,总不可能把这些属性也全自己实现吧,那就太麻烦了。

在这里,我们就可以利用attrs属性,我们把自己封装的Input组件结构一下,他在Dom渲染应该是这样的

<Input v-model="input" placeholder="请输入内容">// Input组件内部<template><inputclass="input"type="text":value="text":class="size"@input.stop="handerInput" /></template>
</Input>

正常来说,我们对组件传入placeholder属性,如果要获取到placeholder那么就需要在props中获取到,但是如果我们用attrs,就可以把这个属性直接加到input标签上。

因此,我们就可以用一行代码,把这些属性全部实现了。

<template><inputclass="input"v-bind="$attrs" // +加上attrstype="text":value="text":class="size"@input.stop="handerInput" />
</template>

演示demo

完整项目demo

结语

Input组件的核心开发功能就是上面这些,其他更多的详细功能开发可以参考Hview-ui项目源码

如果想要了解更多的组件轮子开发,或者组件库开发流程,更多详细的组件开发过程更新在GitHub项目源码,最后觉得我们项目or文章不错可以点个star,点点小手支持一下,也欢迎各路大佬为我们的开源项目添砖加瓦。

http://www.lryc.cn/news/142056.html

相关文章:

  • Day04-Vue基础-监听器-双向绑定-组件通信
  • Java小白基础自学阶段(持续更新...)
  • Vue自定义指令- v-loading封装
  • C++中提供的一些关于查找元素的函数
  • Wlan——STA上线流程与802.11MAC帧讲解以及报文转发路径
  • Python|爬虫和测试|selenium框架模拟登录示例(一)
  • QT的概述
  • Hive 导入csv文件,数据中包含逗号的问题
  • 1、Odoo开发起点
  • Ubuntu22.04 交叉编译树莓派CM4 kernel
  • 稀疏矩阵搜索(两种方法解决:1.暴力+哈希 2.二分法)
  • NodeJS系列教程、笔记
  • 4.4TCP半连接队列和全连接队列
  • 一键实现 Oracle 数据整库同步至 Apache Doris
  • Unity3D软件安装包分享(附安装教程)
  • Vue2向Vue3过度Vue3组合式API
  • ⛳ Docker 安装 MySQL
  • 4.6 TCP面向字节流
  • uniapp返回上一页并刷新
  • LRU cache的实现细节优化——伪结点的技巧
  • 【C/C++】父类指针指向子类对象 | 隐藏
  • NSSCTF——Web题目2
  • 从零到富:探索CSGO搬砖项目的无限可能
  • Uniapp中vuex的使用
  • SpringBoot案例-配置文件-参数配置化
  • android系统启动流程之zygote(Native)启动分析
  • Win10上ffmpeg出现Invalid report file level
  • Vue3 中引入液晶数字字体(通常用于大屏设计)
  • 从 Future 到 CompletableFuture:简化 Java 中的异步编程
  • 【ARMv8 SIMD和浮点指令编程】NEON 乘法指令——乘法知多少?