Javascript 如何将自动调整大小的textarea作为道具传递?在它上面工作';它是自己的,但不是作为道具
我正在为textareas开发一个新组件,希望让它们能够完成三件事<代码>自动对焦,Javascript 如何将自动调整大小的textarea作为道具传递?在它上面工作';它是自己的,但不是作为道具,javascript,vue.js,input,vuejs2,textarea,Javascript,Vue.js,Input,Vuejs2,Textarea,我正在为textareas开发一个新组件,希望让它们能够完成三件事自动对焦,去盎司(仍在进行中)和基于值的自动增长/调整大小 我已经得到了一个基本组件,可以使用它,还有一些我不太熟悉的计算属性。但从我的理解来看,我不需要他们来让这些新道具工作 我的自动对焦作为一个道具工作得很好,但是自动增长/调整大小给我带来了一些麻烦。在一个单独的实例中,我可以让它工作,但是作为这个basecomponent的道具传递,我无法让它工作 当我尝试添加:value=“value”使v-model工作时,我得到一个错
去盎司
(仍在进行中)和基于值的自动增长/调整大小
我已经得到了一个基本组件,可以使用它,还有一些我不太熟悉的计算属性。但从我的理解来看,我不需要他们来让这些新道具工作
我的自动对焦作为一个道具工作得很好,但是自动增长/调整大小给我带来了一些麻烦。在一个单独的实例中,我可以让它工作,但是作为这个basecomponent的道具传递,我无法让它工作
当我尝试添加:value=“value”
使v-model工作时,我得到一个错误:
:value=“value”与同一元素上的v-model冲突,因为后者已在内部扩展为值绑定
我想这是因为它与上面的v-model=“model”
冲突,但我不确定从那里该如何处理它
我已经附上了在底部工作的版本
我的问题是,我在CcInput-App.vue关系中做错了什么,使它不能像下面的隔离版本那样工作
如果您需要更多信息,请随时询问
CcInput
导出默认值{
名称:“CcInput”,
道具:{
/**v型*/
值:{type:[字符串,数字],默认值:''},
valueType:{type:[字符串,未定义],默认值:未定义},
自动对焦:{type:Boolean,默认值:false},
自动增长:{type:Boolean,默认值:false},
},
安装的(){
如果(此为自动对焦){
if(this.propsToPass.type!=='textarea'){
这是focusInput()
}否则{
this.focusTextArea()
}
}
},
数据(){
返回{
innerValue:this.value,
}
},
方法:{
聚焦输入(){
这是。$refs.input.focus()
},
focusTextArea(){
这是。$refs.textArea.focus()
},
},
计算:{
listenersWithoutInput(){
返回{…this.$listeners,输入:undefined}
},
型号:{
得到(){
返回此.value
},
设置(val){
const{propsToPass}=此
如果(propsToPass.type=='number'){
const valAsNumberIfNotNaN=!isNaN(Number(val))?Number(val):val
此.$emit('input',valAsNumberIfNotNaN)
返回
}
此.$emit('input',val)
},
},
propsToPass(){
常量{$attrs,valueType}=此
常量类型=$attrs.type?$attrs.type:valueType==='number'?'number':未定义
返回{…$attrs,type}
},
},
}
.cc输入
最小宽度:0
最大宽度:100%
显示器:flex
柔性包装:nowrap
对齐项目:居中
职位:相对
文本区,输入
填充:10px
最小宽度:0
宽度:100%
最小高度:24px
线高:24px
大纲:无
盒影:无
-webkit外观:无
边界:无
z指数:2
职位:相对
.cc输入
最小宽度:0
最大宽度:100%
显示器:flex
柔性包装:nowrap
对齐项目:居中
职位:相对
文本区,输入
填充:10px
最小宽度:0
宽度:100%
最小高度:24px
线高:24px
大纲:无
盒影:无
-webkit外观:无
边界:无
z指数:2
职位:相对
背景:无
文本区
框大小:边框框
最小高度:100px!重要的
&::之后,&::之前
边界半径:4px
位置:绝对位置
排名:0
底部:0
左:0
右:0
内容:“”
边框样式:实心
过渡:边框颜色300毫秒
&::之后
边框宽度:1px
边框颜色:rgba(0,0,0,0.24)
&::之前
边框宽度:2倍
边框颜色:透明
&:焦点在::之后
边框颜色:透明
&:焦点在::之前
边框颜色:紫色
App.vue
自动对焦
去盎司
自传
从“../components/CcInput.vue”导入CcInput
导出默认值{
名称:“应用程序”,
组成部分:{
CcInput,
},
}
*
宽度:50vw
左:50%
.文本区
文本对齐:居中
自动增长.vue
导出默认值{
姓名:'自动增长',
},
方法:{
自动增长(e){
e、 target.style.height='auto'
e、 target.style.height=`${e.target.scrollHeight}px`
},
},
}
.文本区
框大小:边框框
宽度:100%
填充:20px
边界半径:8px
该bug位于propsToPass
computed属性中,其中:
//Ccinput.vue
导出默认值{
计算:{
propsToPass(){
常量{$attrs,valueType}=此
常量类型=$attrs.type?$attrs.type:valueType==='number'?'number':未定义
返回{…$attrs,type}
},
}
}
给定的值类型
“textarea”
,propsToPass.type
为未定义
,不满足自动增长行为:
解决此问题的一种方法是更新条件以检查valueType
,而不是propsToPass.type
:
并更新为使用valueType
:
//如果(this.propsToPass.type!=='textarea'){
if(this.valueType!=='textarea'){
作为旁白,您有:
//this.$refs.textArea.focus()❌
^
这是。$refs.textarea.focus()✅
<template>
<div class="cc-input">
<input
v-if="propsToPass.type !== 'textarea'"
v-bind="propsToPass"
v-model="model"
ref="input"
/>
<textarea
v-if="propsToPass.type === 'textarea'"
v-bind="propsToPass"
v-model="model"
ref="textarea"
/>
</div>
</template>
<script>
export default {
name: 'CcInput',
props: {
/** v-model */
value: { type: [String, Number], default: '' },
valueType: { type: [String, undefined], default: undefined },
autofocus: { type: Boolean, default: false },
autogrow: { type: Boolean, default: false },
},
mounted() {
if (this.autofocus) {
if (this.propsToPass.type !== 'textarea') {
this.focusInput()
} else {
this.focusTextArea()
}
}
},
data() {
return {
innerValue: this.value,
}
},
methods: {
focusInput() {
this.$refs.input.focus()
},
focusTextArea() {
this.$refs.textArea.focus()
},
},
computed: {
listenersWithoutInput() {
return { ...this.$listeners, input: undefined }
},
model: {
get() {
return this.value
},
set(val) {
const { propsToPass } = this
if (propsToPass.type === 'number') {
const valAsNumberIfNotNaN = !isNaN(Number(val)) ? Number(val) : val
this.$emit('input', valAsNumberIfNotNaN)
return
}
this.$emit('input', val)
},
},
propsToPass() {
const { $attrs, valueType } = this
const type = $attrs.type ? $attrs.type : valueType === 'number' ? 'number' : undefined
return { ...$attrs, type }
},
},
}
</script>
<style lang="sass">
.cc-input
min-width: 0
max-width: 100%
display: flex
flex-wrap: nowrap
align-items: center
position: relative
textarea, input
padding: 10px
min-width: 0
width: 100%
min-height: 24px
line-height: 24px
outline: none
box-shadow: none
-webkit-appearance: none
border: none
z-index: 2
position: relative
.cc-input
min-width: 0
max-width: 100%
display: flex
flex-wrap: nowrap
align-items: center
position: relative
textarea, input
padding: 10px
min-width: 0
width: 100%
min-height: 24px
line-height: 24px
outline: none
box-shadow: none
-webkit-appearance: none
border: none
z-index: 2
position: relative
background: none
textarea
box-sizing: border-box
min-height: 100px !important
&::after, &::before
border-radius: 4px
position: absolute
top: 0
bottom: 0
left: 0
right: 0
content: ''
border-style: solid
transition: border-color 300ms ease
&::after
border-width: 1px
border-color: rgba(0, 0, 0, 0.24)
&::before
border-width: 2px
border-color: transparent
&:focus-within::after
border-color: transparent
&:focus-within::before
border-color: purple
</style>
<template>
<div class="home">
<div class="textarea">
autofocus
<CcInput valueType="textarea" :autofocus="true" />
</div>
<div class="textarea">
debounce
<CcInput valueType="textarea" :debounce="300" />
</div>
<div class="textarea">
autogrow
<CcInput valueType="textarea" :autogrow="true" />
</div>
</div>
</div>
</template>
<script>
import CcInput from '../components/CcInput.vue'
export default {
name: 'App',
components: {
CcInput,
},
}
</script>
<style lang="sass" scoped>
*
width: 50vw
left: 50%
.textarea
text-align: center
</style>
<template>
<div>
<textarea class="textarea" name="body" id="body" @input="autogrow($event)"></textarea>
<textarea class="textarea" name="anotherbody" id="anotherbody"></textarea>
</div>
</template>
<script>
export default {
name: 'Autogrow',
},
methods: {
autogrow(e) {
e.target.style.height = 'auto'
e.target.style.height = `${e.target.scrollHeight}px`
},
},
}
</script>
<style lang="sass" scoped>
.textarea
box-sizing: border-box
width: 100%
padding: 20px
border-radius: 8px
</style>