I have an AppReplyToMessage
ponent that is supposed to send data to the AppSendMessage
ponent to notify it that the message being sent is a reply. I'm doing it as follows; The AppReplyToMessage
ponent:
<script setup>
import { provide } from "vue";
import AppSendMessage from "../AppSendMessage.vue";
let props = defineProps({
message: {
type: Object,
required: true,
},
});
let message = toRefs(props).message;
const replyToMessage = () => {
const message = {
reply: true,
};
provide("reply", message);
};
</script>
<template>
<button@click="replyToMessage">
Reply
</button>
</template>
and in the AppSendMessage
ponent I'm receiving the data as follows:
<script setup>
const reply = inject("reply", null);
</script>
The code though is not working an I'm getting the error [Vue warn]: provide() can only be used inside setup().
in the console.
I have an AppReplyToMessage
ponent that is supposed to send data to the AppSendMessage
ponent to notify it that the message being sent is a reply. I'm doing it as follows; The AppReplyToMessage
ponent:
<script setup>
import { provide } from "vue";
import AppSendMessage from "../AppSendMessage.vue";
let props = defineProps({
message: {
type: Object,
required: true,
},
});
let message = toRefs(props).message;
const replyToMessage = () => {
const message = {
reply: true,
};
provide("reply", message);
};
</script>
<template>
<button@click="replyToMessage">
Reply
</button>
</template>
and in the AppSendMessage
ponent I'm receiving the data as follows:
<script setup>
const reply = inject("reply", null);
</script>
The code though is not working an I'm getting the error [Vue warn]: provide() can only be used inside setup().
in the console.
- Are you using vite or Vue cli? – Boussadjra Brahim Commented Feb 22, 2023 at 13:28
- I am using Vite – user3714932 Commented Feb 22, 2023 at 13:57
2 Answers
Reset to default 4provide
should be used at the top level of setup, not within another function within setup.
First create an empty ref, and pass that to the provide function. Then within your replyToMessage
function, set the value of the ref when the button is clicked.
<script setup>
import { provide, ref } from "vue";
// ...
const reply = ref(null);
provide("reply", reply);
const replyToMessage = () => {
const message = {
reply: true,
};
reply.value = message;
};
</script>
<template>
<button @click="replyToMessage">
Reply
</button>
</template>
Docs
Disregarding the small errors you have in your source code, like forgotten import { inject } from "vue"
in the AppSendMessage
ponent, you have two important design problems.
The Vue
props
are readonly. Do not try to mutate theprops
in ponents!The Vue warning states that you should run
provide()
only fromsetup()
or from<setup script>
.
You call setup()
from a lambda function.
const replyToMessage = () => {
const message = {
reply: true,
};
provide("reply", message);
};
You should run provide("reply", message)
directly from <setup script>
- And then, you declare a new
message
constant in the lambda function, which has no relation to yourmessage
prop.
Please read the Vue Docs about Components and Provide / Inject thoroughly and check the SFC Playground with Provide / Inject
example.
Here is the SFC Playground with the solution
const reply = ref({});
provide("reply", reply);
const replyToMessage = () => {
reply.value.message = props.message;
reply.value.reply = true;
};