I am migrating to Vue SFC and have problem using computed property.
With the following code, I want to create two rows, and the visibility of the bottom row (the content row) can be toggled by clicking the top row (the title row).
<!-- components/Note.vue -->
<script setup>
import { marked } from "marked";
import { ref, computed } from "vue";
const props = defineProps({
id: Number,
title: String,
create: String,
content: String
});
const showContent = ref(false);
const elContent = ref(null);
const scrollHeight = computed(() => {
return elContent.value.scrollHeight + "px";
});
const markedContent = computed(() => {
return marked.parse(content.value);
})
</script>
<template>
<div class="row" @click="showContent=!showContent">
<div class="col-9">{{ title }}</div>
<div class="col-3">{{ create }}</div>
</div>
<div class="row" :style="{height:showContent?scrollHeight:0}" ref="elContent">
<div class="col">{{ markedContent }}</div>
</div>
</template>
Here is the error message
[Vue warn]: Unhandled error during execution of render function (9)
"
"
" at <Note"
"id=27"
"title=\"1Lorem Ipsum\""
" ..."
">"
"
"
" at <App>"
[Vue warn]: Unhandled error during execution of scheduler flush. This is likely a Vue internals bug. Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/core (9)
"
"
" at <Note"
"id=27"
"title=\"1Lorem Ipsum\""
" ..."
">"
"
"
" at <App>"
Unhandled Promise Rejection: ReferenceError: Can't find variable: content
However, if I don't use computed property, but the marked.parse method directly in the template, then everything works smoothly.
<!-- This is fine -->
<div class="row" :style="{height:showContent?scrollHeight:0}" ref="elContent">
<div class="col">{{ marked.parse(content) }}</div>
</div>
I hope someone can tell me why this happens and how should I use computed property in script setup.
Use the
props.probNamepattern to access props in script-setup files. However, in the template section, you must useprobNamedirectly.So in your case, use
props.contentinstead ofcontentto address the issue.The
propsname comes from the definition of your props, where you choose a variable name to hold all properties.Access props directly in the setup
If you wish to access props directly (as in the template), you can destruct the
propsat the place:UPDATE: A note from the comments
Keep in mind that destructing props is not straightforward. It brings more coding and complexity, therefore I avoid it.
To tackle the losing reactivity problem, you need to either use
toRefmanually or leverage the Vue Macros plugin.