组件属性在从监视器中发射时未更新。

huangapple go评论68阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2023年7月11日 07:30:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/76657897.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定