-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Change needed for Vue 3 (does not use $el) #35
Comments
+1 |
@jijoel Thank you for providing the awesome workaround. I'd like to a bit make changes like: --- a/TextareaAutoresize.vue 2022-02-02 16:31:23.000000000 +0900
+++ b/TextareaAutoresize.vue 2022-02-02 16:31:23.000000000 +0900
@@ -22,7 +22,7 @@
export default {
name: 'TextareaAutosize',
props: {
- value: {
+ modelValue: {
type: [String, Number],
default: ''
},
@@ -78,7 +78,7 @@
}
},
watch: {
- value (val) {
+ modelValue (val) {
this.val = val
},
val (val) {
@@ -123,7 +123,7 @@
}
},
created () {
- this.val = this.value
+ this.val = this.modelValue
},
mounted () {
this.resize()
See: https://v3.vuejs.org/guide/migration/v-model.html Best regards. |
in case somebody wants to use this component within a Vue3 typescript setup; <template>
<textarea
ref="textareaRef"
v-model="value"
:style="computedStyles"
@focus="resize"
/>
</template>
<script lang="ts">
import { defineComponent, computed, ref, nextTick, CSSProperties, onMounted, PropType, onUpdated } from 'vue'
type CssAttribs = 'resize'|'overflow'|'height';
export default defineComponent({
props: {
modelValue: {
type: [String, Number],
default: ''
},
autosize: {
type: Boolean,
default: true
},
minHeight: {
type: [Number],
required: false,
},
maxHeight: {
type: [Number],
required: false,
},
important: {
type: [Boolean, Array] as PropType<CssAttribs[]|boolean>,
default: false
}
},
emits: ['update:modelValue'],
setup (props) {
const height = ref('0');
const textareaRef = ref();
const maxHeightScroll = ref(false);
const value = ref(props.modelValue);
const isImportantAttr = (attr: CssAttribs) => {
return props.important === true
|| (Array.isArray(props.important) && props.important.includes(attr));
}
const computedStyles = computed<CSSProperties|undefined>(() => {
if (!props.autosize) {
return undefined;
}
return {
resize: !isImportantAttr('resize') ? 'none' : 'none !important',
height: height.value,
overflow: maxHeightScroll.value
? 'auto'
: (!isImportantAttr('overflow') ? 'hidden' : 'hidden !important')
} as CSSProperties; // !important is not always allowed for `CSSProperties`
});
const resize = () => {
const important = isImportantAttr('height') ? 'important' : ''
height.value = `auto${important ? ' !important' : ''}`
nextTick(() => {
let contentHeight = textareaRef.value.scrollHeight + 1
if (props.minHeight) {
contentHeight = contentHeight < props.minHeight ? props.minHeight : contentHeight
}
if (props.maxHeight) {
if (contentHeight > props.maxHeight) {
contentHeight = props.maxHeight
maxHeightScroll.value = true
} else {
maxHeightScroll.value = false
}
}
const heightVal = `${contentHeight}px`
height.value = `${heightVal}${important ? ' !important' : ''}`;
});
}
onMounted(() => {
resize();
});
return {
textareaRef,
resize,
computedStyles,
value,
maxHeightScroll: false,
height: 'auto'
}
},
watch: {
modelValue (val) {
this.value = val
this.$nextTick(this.resize)
this.$emit('update:modelValue', val)
},
minHeight () {
this.$nextTick(this.resize)
},
maxHeight () {
this.$nextTick(this.resize)
},
autosize (val) {
if (val) this.resize()
}
},
})
</script> |
I think you want to watch |
Yes, in order for the component to work you need to add an extra watch for
|
For vue3 I would recommend using vueuse | useTextareaAutosize |
Also, for Vue 3 you can use v-autosize, it's a Vue wrapper for battle-tested jackmoore/autosize. It is implemented as a directive without any options, which is easier to use IMO |
In Vue 3, components are no longer limited to only 1 root element, so we will no longer have an $el. I am currently experimenting with Vue 3, and found that changing the component source like this will make it work:
I don't know the other changes that will be needed to make a distributable version, but found that (for now) it does work to copy the
TextareaAutosize.vue
file (with the above changes) into my own code base, and call it like this:The text was updated successfully, but these errors were encountered: