相关样式部分
.k-input__suffix,.k-input__prefix {position: absolute;right: 10px;height: 100%;top: 0;display: flex;align-items: center;cursor: pointer;color: #c0c4cc;font-size: 15px;}.no-cursor {cursor: default;}.k-input--prefix.k-input__inner {padding-left: 30px;}.k-input__prefix {position: absolute;width: 20px;cursor: default;left: 10px;}
在app.vue
中使用效果如下
<template><div class="input-demo"><Input v-model="tel" suffixIcon="edit" placeholder="请输入内容" /><Input v-model="tel" prefixIcon="edit" placeholder="请输入内容" /></div></template><script lang="ts" setup>import { Input } from "kitty-ui";import { ref } from "vue";const tel = ref("");</script><style lang="less">.input-demo {width: 200px;}</style>
文章插图
文本域将
type
属性的值指定为textarea
即可展示文本域模式 。它绑定的事件以及属性和input
基本一样<template><div class="k-textarea" v-if="attrs.type === 'textarea'"><textareaclass="k-textarea__inner":style="textareaStyle"v-bind="attrs"ref="textarea":value="https://www.huyubaike.com/biancheng/inputProps.modelValue"@input="changeInputVal"/></div><divv-elseclass="k-input"@mouseenter="isEnter = true"@mouseleave="isEnter = false":class="styleClass">...</div></template>
样式基本也就是focus
,hover
改变 border 颜色.k-textarea {width: 100%;.k-textarea__inner {display: block;padding: 5px 15px;line-height: 1.5;box-sizing: border-box;width: 100%;font-size: inherit;color: #606266;background-color: #fff;background-image: none;border: 1px solid #dcdfe6;border-radius: 4px;&::placeholder {color: #c2c2ca;}&:hover {border: 1px solid #c0c4cc;}&:focus {outline: none;border: 1px solid #409eff;}}}
文章插图
可自适应高度文本域组件可以通过接收
autosize
属性来开启自适应高度,同时autosize
也可以传对象形式来指定最小和最大行高type AutosizeObj = {minRows?: numbermaxRows?: number}type InputProps = {autosize?: boolean | AutosizeObj}
具体实现原理是通过监听输入框值的变化来调整textarea
的样式,其中用到了一些原生的方法譬如window.getComputedStyle(获取原生css对象)
,getPropertyValue(获取css属性值)
等,所以原生js
忘记的可以复习一下...const textareaStyle = ref<any>()const textarea = shallowRef<HTMLTextAreaElement>()watch(() => inputProps.modelValue, () => {if (attrs.type === 'textarea' && inputProps.autosize) {const minRows = isObject(inputProps.autosize) ? (inputProps.autosize as AutosizeObj).minRows : undefinedconst maxRows = isObject(inputProps.autosize) ? (inputProps.autosize as AutosizeObj).maxRows : undefinednextTick(() => {textareaStyle.value = https://www.huyubaike.com/biancheng/calcTextareaHeight(textarea.value!, minRows, maxRows)})}}, { immediate: true })
其中calcTextareaHeight
为const isNumber = (val: any): boolean => {return typeof val === 'number'}//隐藏的元素let hiddenTextarea: HTMLTextAreaElement | undefined = undefined//隐藏元素样式const HIDDEN_STYLE = `height:0 !important;visibility:hidden !important;overflow:hidden !important;position:absolute !important;z-index:-1000 !important;top:0 !important;right:0 !important;`const CONTEXT_STYLE = ['letter-spacing','line-height','padding-top','padding-bottom','font-family','font-weight','font-size','text-rendering','text-transform','width','text-indent','padding-left','padding-right','border-width','box-sizing',]type NodeStyle = {contextStyle: stringboxSizing: stringpaddingSize: numberborderSize: number}type TextAreaHeight = {height: stringminHeight?: string}function calculateNodeStyling(targetElement: Element): NodeStyle {//获取实际textarea样式返回并赋值给隐藏的textareaconst style = window.getComputedStyle(targetElement)const boxSizing = style.getPropertyValue('box-sizing')const paddingSize =Number.parseFloat(style.getPropertyValue('padding-bottom')) +Number.parseFloat(style.getPropertyValue('padding-top'))const borderSize =Number.parseFloat(style.getPropertyValue('border-bottom-width')) +Number.parseFloat(style.getPropertyValue('border-top-width'))const contextStyle = CONTEXT_STYLE.map((name) => `${name}:${style.getPropertyValue(name)}`).join(';')return { contextStyle, paddingSize, borderSize, boxSizing }}export function calcTextareaHeight(targetElement: HTMLTextAreaElement,minRows = 1,maxRows?: number): TextAreaHeight {if (!hiddenTextarea) {//创建隐藏的textareahiddenTextarea = document.createElement('textarea')document.body.appendChild(hiddenTextarea)}//给隐藏的teatarea赋予实际textarea的样式以及值(value)const { paddingSize, borderSize, boxSizing, contextStyle } =calculateNodeStyling(targetElement)hiddenTextarea.setAttribute('style', `${contextStyle};${HIDDEN_STYLE}`)hiddenTextarea.value = https://www.huyubaike.com/biancheng/targetElement.value || targetElement.placeholder ||''//隐藏textarea整个高度,包括内边距padding,borderlet height = hiddenTextarea.scrollHeightconst result = {} as TextAreaHeight//判断boxSizing,返回实际高度if (boxSizing === 'border-box') {height = height + borderSize} else if (boxSizing === 'content-box') {height = height - paddingSize}hiddenTextarea.valuehttps://www.huyubaike.com/biancheng/= ''//计算单行高度const singleRowHeight = hiddenTextarea.scrollHeight - paddingSizeif (isNumber(minRows)) {let minHeight = singleRowHeight * minRowsif (boxSizing === 'border-box') {minHeight = minHeight + paddingSize + borderSize}height = Math.max(minHeight, height)result.minHeight = `${minHeight}px`}if (isNumber(maxRows)) {let maxHeight = singleRowHeight * maxRows!if (boxSizing === 'border-box') {maxHeight = maxHeight + paddingSize + borderSize}height = Math.min(maxHeight, height)}result.height = `${height}px`hiddenTextarea.parentNode?.removeChild(hiddenTextarea)hiddenTextarea = undefinedreturn result}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Vue3实现动态导入Excel表格数据
- Vue3 企业级优雅实战 - 组件库框架 - 3 搭建组件库开发环境
- 带你从0到1开发AI图像分类应用
- 从0到1搭建redis6.0.7续更~
- 从0到1搭建redis6.0.7
- Windows操作系统搭建Lsky Pro
- 红米k40参数详细参数_红米k40参数和配置
- 如何破解压缩包的密码从网盘里面下载了一个压缩包,解压的时候需要输入密码,不知道密码是什么,该怎么
- 【深入浅出 Yarn 架构与实现】1-2 搭建 Hadoop 源码阅读环境
- 【炫丽】从0开始做一个WPF+Blazor对话小程序