Либо у меня базовое непонимание Vue.js, либо я нашел ошибку. Я могу воспроизвести эту ошибку (?) в минимальном примере ниже.
Компонент App.vue
имеет реактивную message
переменную, которая передается дочернему элементу Child.vue
в качестве реквизита. Это сообщение можно изменить с помощью кнопки. Это прекрасно работает. Однако, когда вы предупреждаете сообщение в дочернем элементе, вы всегда будете получать первое сообщение — оно вообще не обновляется. Кажется, что сообщение обновляется только в разметке, а не в JavaScript. Я действительно смущен таким поведением.
<script setup>
import { ref, computed } from "vue";
import Child from "./components/Child.vue";
let index = ref(0);
let messages = ["hi", "there", "this", "is", "strange"];
let message = computed(() => messages[index.value]);
function change_message() {
index.value++;
if (index.value === messages.length) {
index.value = 0;
}
}
</script>
<template>
<Child :message = "message"></Child>
<div>
<button @click = "change_message">Change message</button>
</div>
</template>
<script setup>
const { message } = defineProps(["message"]);
function alert_message() {
window.alert(message);
}
</script>
<template>
<h1>
{{ message }}
</h1>
<button @click = "alert_message">Alert message</button>
</template>
Есть обходной путь: не разрушайте реквизит в дочернем элементе. Так что напишите const props = defineProps(["message"]);
, а затем используйте window.alert(props.message);
. Однако в реальном приложении Vue это приведет к довольно раздутому коду. Я не хочу постоянно носить с собой props.
.
Когда вы разрушаете реквизит, вы теряете реактивность. В вашем случае можно использовать toRefs:
Child.vue
<script setup>
import { toRefs } from "vue";
const props = defineProps(["message"]);
const { message } = toRefs(props);
function alert_message() {
window.alert(message.value);
}
</script>
<template>
<h1>
{{ message }}
</h1>
<button @click = "alert_message()">Alert message</button>
</template>
https://codesandbox.io/s/nameless-water-jwhw90?file=/src/components/Child.vue
В любом случае, это стандарт для использования props.<your_prop>
, когда это необходимо, даже для реальных приложений Vue.
Спасибо! Это прекрасно работает. Однако теперь мне нужно все время писать «значение». Неужели нет другого пути? (Я пришел из Svelte, где вся эта хрень с рефами и значениями не нужна, все реактивно.)