ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Vue3文本域(Textarea)

Vue3文本域(Textarea) 效果如下图在线预览APIsTextarea参数说明类型默认值width文本域宽度单位pxstring | number‘100%’allowClear可以点击清除图标删除内容booleanfalseautoSize自适应内容高度boolean | {minRows?: number, maxRows?: number}falsedisabled是否禁用booleanfalseplaceholder文本域输入的占位符stringundefinedmaxlength文字最大长度numberundefinedshowCount是否展示字数booleanfalsevalue v-model文本域内容stringundefinedEvents名称说明类型change文本域内容变化时的回调(e: Event) voidenter按下回车的回调(e: Event) voidcompositionstart使用文本合成系统即输入法编辑器开始新的输入时的回调(e: CompositionEvent) voidcompositionend当文本段落的组成完成或取消时触发的回调(e: CompositionEvent) void创建文本域组件Textarea.vue其中引入使用了以下工具函数获取依赖注入 useInjectscript setup langtsimport{ref,computed,watch,onMounted,nextTick}fromvueimport{useInject}fromcomponents/utilsexportinterfaceProps{width?:string|number// 文本域宽度单位 pxallowClear?:boolean// 可以点击清除图标删除内容autoSize?:boolean|{minRows?:number;maxRows?:number}// 自适应内容高度disabled?:boolean// 是否禁用placeholder?:string// 文本域输入的占位符maxlength?:number// 文字最大长度showCount?:boolean// 是否展示字数value?:string// (v-model) 文本域内容valueModifiers?:object// 用于访问组件的 v-model 上添加的修饰符}constpropswithDefaults(definePropsProps(),{width:100%,allowClear:false,autoSize:false,disabled:false,placeholder:undefined,maxlength:undefined,showCount:false,value:,valueModifiers:()({})})consttextareaRefrefHTMLElement|null(null)// textarea 元素引用constisComposingrefboolean(false)// 是否正在使用文本合成系统输入中consttextareaValuerefstring()// 文本域的值constareaHeightrefnumber(32)const{colorPalettes,shadowColor}useInject(Textarea)// 主题色注入constemitsdefineEmits([update:value,compositionstart,compositionend,change,enter])consttextareaWidthcomputed((){if(typeofprops.widthnumber){return${props.width}px}returnprops.width})constautoSizeStylecomputed((){if(typeofprops.autoSizeobject){conststyle:{min-height?:string;max-height?:string;[propName:string]:any}{height:${areaHeight.value}px,resize:none}if(minRowsinprops.autoSize){style[min-height]${(props.autoSize.minRowsasnumber)*2210}px}if(maxRowsinprops.autoSize){style[max-height]${(props.autoSize.maxRowsasnumber)*2210}px}returnstyle}if(typeofprops.autoSizeboolean){if(props.autoSize){return{height:${areaHeight.value}px,resize:none}}return{}}})constshowClearcomputed((){return!props.disabledprops.allowCleartextareaValue.value})constshowCountNumcomputed((){if(props.maxlength){return${textareaValue.value?textareaValue.value.length:0}/${props.maxlength}}returntextareaValue.value?textareaValue.value.length:0})constlazyTextareacomputed((){returnlazyinprops.valueModifiers})watch(()props.value,async(to){if(textareaValue.value!to){textareaValue.valueto}if(JSON.stringify(autoSizeStyle.value)!{}){areaHeight.value32awaitnextTick()getAreaHeight()}},{immediate:true,flush:post})onMounted((){getAreaHeight()})functiongetAreaHeight():void{areaHeight.value(textareaRef.valueasHTMLElement).scrollHeight2}// 文本合成系统即输入法编辑器开始新的输入合成时会触发functiononCompositionStart(e:CompositionEvent):void{isComposing.valuetrueemits(compositionstart,e)}// 当文本段落的组成完成或取消时触发 (具有特殊字符的触发需要一系列键和其他输入如语音识别或移动中的字词建议)functiononCompositionEnd(e:CompositionEvent):void{isComposing.valuefalseemits(compositionend,e)constchangeEventnewEvent(change)e.target?.dispatchEvent(changeEvent)}functiononInput(e:Event):void{if(!isComposing.value){consttargete.targetasHTMLInputElement textareaValue.valuetarget.valueif(!lazyTextarea.value){emits(update:value,target.value)// 保证在 change 回调时能获取到最新数据emits(change,e)}}}functiononChange(e:Event):void{consttargete.targetasHTMLInputElementif(target.value!props.value){emits(update:value,target.value)// 保证在 change 回调时能获取到最新数据emits(change,e)}}functiononEnter(e:KeyboardEvent):void{if(isComposing.value){return}emits(enter,e)}functiononClear():void{textareaValue.valueemits(update:value,)textareaRef.value?.focus()}/scripttemplatedivclasstextarea-wrap:class{ show-count: showCount }:style--textarea-width:${textareaWidth}; --textarea-primary-color-hover:${colorPalettes[4]}; --textarea-primary-color-focus:${colorPalettes[4]}; --textarea-primary-shadow-color:${shadowColor};:data-countshowCountNumtextarea reftextareaReftypehiddenclasstextarea-item:class{ clear-class: showClear, textarea-disabled: disabled }:styleautoSizeStyle:valuetextareaValue:placeholderplaceholder:maxlengthmaxlength:disableddisabledcompositionstartonCompositionStartcompositionendonCompositionEndinputonInputchangeonChangekeydown.enteronEnter/svg v-ifshowClearclassclear-svgclickonClearfocusablefalsedata-iconclose-circlewidth1emheight1emfillcurrentColoraria-hiddentrueviewBox64 64 896 896path dM512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 01-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z/path/svg/div/templatestyle langlessscoped.textarea-wrap{position:relative;display:inline-block;width:var(--textarea-width);.textarea-item{width:100%;min-width:0;min-height:32px;max-width:100%;height:auto;padding:4px 11px;color:rgba(0,0,0,0.88);font-size:14px;line-height:1.5714285714285714;list-style:none;transition:all0.3s,height 0s;resize:vertical;position:relative;z-index:9;display:inline-block;vertical-align:bottom;text-overflow:ellipsis;background-color:#ffffff;border:1px solid #d9d9d9;border-radius:6px;outline:none;:hover{border-color:var(--textarea-primary-color-hover);z-index:1;}:focus-within{border-color:var(--textarea-primary-color-focus);box-shadow:0002pxvar(--textarea-primary-shadow-color);outline:0;}}.clear-class{padding-right:24px;}textarea:disabled{color:rgba(0,0,0,0.25);}textarea::-webkit-input-placeholder{color:rgba(0,0,0,0.25);}textarea:-moz-placeholder{color:rgba(0,0,0,0.25);}textarea::-moz-placeholder{color:rgba(0,0,0,0.25);}textarea:-ms-input-placeholder{color:rgba(0,0,0,0.25);}.clear-svg{position:absolute;top:9px;right:8px;z-index:99;display:inline-block;font-size:12px;color:rgba(0,0,0,0.25);fill:currentColor;cursor:pointer;transition:color0.3s;:hover{color:rgba(0,0,0,0.45);}}.textarea-disabled{color:rgba(0,0,0,0.25);background-color:rgba(0,0,0,0.04);cursor:not-allowed;:hover{border-color:#d9d9d9;}:focus-within{border-color:#d9d9d9;box-shadow:none;}}}.show-count{::after{font-size:14px;color:rgba(0,0,0,0.45);white-space:nowrap;content:attr(data-count);pointer-events:none;float:right;}}/style在要使用的页面引入其中引入使用了以下组件Vue3间距SpaceVue3警告提示Alertscript setup langtsimportTextareafrom./Textarea.vueimport{ref,watchEffect}fromvueconstvalueref()constlazyValueref()watchEffect((){console.log(value,value.value)})watchEffect((){console.log(lazyValue,lazyValue.value)})functiononChange(e:Event){console.log(change,e)}functiononEnter(e:KeyboardEvent){console.log(enter,e)}/scripttemplatedivh1{{$route.name}}{{$route.meta.title}}/h1h2classmt30 mb10基本使用/h2Space verticalAlert typeinfo.lazy:br/默认情况下v-model 会在每次 input事件后更新数据(IME拼字阶段的状态例外)。br/你可以添加 lazy 修饰符来改为在每次 change 事件后更新数据br/{{Textarea v-model:value.lazymsg /}}/AlertTextarea v-model:valuevalueplaceholderBasic usage rows 2:rows2changeonChangeenteronEnter/Textarea v-model:value.lazylazyValueplaceholderLazy usage rows 2:rows2changeonChangeenteronEnter//Spaceh2classmt30 mb10适应文本高度的文本域/h2Textarea:width360v-model:valuevalueplaceholderAutosize height based on content linesauto-size/h2classmt30 mb10自定义行数/h2Textarea:width360v-model:valuevalueplaceholderAutosize height with minimum and maximum number of lines:auto-size{ minRows: 2, maxRows: 5 }/h2classmt30 mb10带清除图标/h2Textarea:width360v-model:valuevalueplaceholdertextarea with clear iconallow-clear/h2classmt30 mb10带数字提示/h2Textarea:width360v-model:valuevalueplaceholdertextarea with show countshow-count:maxlength10/h2classmt30 mb10禁用/h2Textarea:width360v-model:valuevalueplaceholderdisabled textareadisabled//div/template
返回列表