英文:
Component prop is not updated when emitting from a watcher
问题
我有一个在观察器中发出事件的问题。我有这个组件,它作为自定义输入组件工作,正如您所见,我正在观察inputValue的更改,并将新值发出为prop modelValue 来进行更改。不幸的是,它似乎不起作用,当我调试时,modelValue 仍然保持不变(尽管我可以看到inputValue和newValue打印出更新的值)。
请问可能的问题是什么呢?
PS:观察器受到inputValue更改的触发。
<template>
<div class="col-span-12">
<div class="flex">
<span
contenteditable="true"
class="editable"
:class="[fontBold ? 'font-bold' : '']"
:placeholder="placeholder"
@input="handleInput"
@focusout="$emit('savingValue')"
ref="editableSpan"
>
{{ inputValue }}
</span>
</div>
</div>
</template>
<script setup>
import { ref, nextTick, onMounted, watch } from "vue";
const emit = defineEmits(["update:modelValue","savingValue"]);
const props = defineProps({
modelValue: {
type: String,
required: true,
},
name: {
type: String,
default: "",
},
type: {
type: String,
default: "text",
},
required: {
type: Boolean,
default: false,
},
disabled: {
type: Boolean,
default: false,
},
label: {
type: String,
default: "",
},
placeholder: {
type: String,
default: "",
},
fontBold: {
type: Boolean,
default: false,
},
});
const inputValue = ref(props.modelValue);
const editableSpan = ref(null);
watch(inputValue, (newValue) => {
emit("update:modelValue", newValue);
});
const handleInput = () => {
inputValue.value = editableSpan.value.innerText;
};
</script>
<style scoped>
[contenteditable="true"]:empty {
color: #bbb;
}
.editable {
display: inline-block;
padding: 3px 2px;
outline: none;
cursor: text;
background-color: #edf3f1;
white-space: nowrap;
overflow: hidden;
}
[contenteditable="true"]:empty:before {
content: attr(placeholder);
}
</style>
我知道我可以使用输入框而不是 span,但我不能不知道可能的问题就离开。
英文:
I have an issue with emitting from a watcher. I have this component that works as a custom input component and as you can see I'm watching changes on inputValue and I emit the new value for the prop modelValue to change. Unfortunately it doesn't seem to work and modelValue just stays the same as I debug (although I can have inputValue and newValue printing the updated value).
What would be the problem please?
PS: The watcher gets well triggered by changes on inputValue.
<template>
<div class="col-span-12">
<div class="flex">
<span
contenteditable="true"
class="editable"
:class="[fontBold ? 'font-bold' : '']"
:placeholder="placeholder"
@input="handleInput"
@focusout="$emit('savingValue')"
ref="editableSpan"
>
{{ inputValue }}
</span>
</div>
</div>
</template>
<script setup>
import { ref, nextTick, onMounted, watch } from "vue";
const emit = defineEmits(["update:modelValue","savingValue"]);
const props = defineProps({
modelValue: {
type: String,
required: true,
},
name: {
type: String,
default: "",
},
type: {
type: String,
default: "text",
},
required: {
type: Boolean,
default: false,
},
disabled: {
type: Boolean,
default: false,
},
label: {
type: String,
default: "",
},
placeholder: {
type: String,
default: "",
},
fontBold: {
type: Boolean,
default: false,
},
});
const inputValue = ref(props.modelValue);
const editableSpan = ref(null);
watch(inputValue, (newValue) => {
emit("update:modelValue", newValue);
});
const handleInput = () => {
inputValue.value = editableSpan.value.innerText;
};
</script>
<style scoped>
[contenteditable="true"]:empty {
color: #bbb;
}
.editable {
display: inline-block;
padding: 3px 2px;
outline: none;
cursor: text;
background-color: #edf3f1;
white-space: nowrap;
overflow: hidden;
}
[contenteditable="true"]:empty:before {
content: attr(placeholder);
}
</style>
I know I could use an input instead of a span but I can't just leave without knowing what could be the issue.
答案1
得分: 0
我仔细阅读了Vue文档,并进行了一些研究,我发现尽管代码没问题,但我的逻辑不太对。prop 不应该被更新(即使有一些方法可以更新 props,但最好是单向的)。我在这里犯了一个错误,当尝试使用这个组件时,我期望在父组件上使用 :modelValue="somevariable" 来访问值。结果发现我应该使用 v-model="somevariable"。感谢您的帮助。
英文:
I went through vue documentation carefully and with some research also i found out that my logic wasn't quite good despite the code being okay. The prop is not supposed to be updated (and even though there are ways to update props they should be one way ideally).
My mistake here was that when trying to use this component i expected :modelValue="somevariable" on the parent component to be the way for me to access the value. Turns out i should be using v-mode="somevariable".
Thanks for your help.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论