英文:
Why Vue Can't Find Variable When Render Computed Property In Setup Script To Template
问题
以下是要翻译的代码部分:
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>
这是您提供的代码部分的中文翻译。
英文:
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.
答案1
得分: 1
Use the props.probName
pattern to access props in script-setup files. However, in the template section, you must use probName
directly.
So in your case, use props.content
instead of content
to address the issue.
const markedContent = computed(() => {
return marked.parse(props.content);
//return marked.parse(props.content.value);
})
The props
name comes from the definition of your props, where you choose a variable name to hold all properties.
// Here you've defined a variable name (props) that represents all properties
const props = defineProps({
id: Number,
title: String,
create: String,
content: String
});
Access props directly in the setup
If you wish to access props directly (as in the template), you can destruct the props
at the place:
const {content, id, title, create} = defineProps({
id: Number,
title: String,
create: String,
content: String
});
const markedContent = computed(() => {
return marked.parse(content);
})
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.
> You need to always access props as props.x in order to retain reactivity. This means you cannot destructure defineProps because the resulting destructured variables are not reactive and will not update. (link)
To tackle the losing reactivity problem, you need to either use toRef
manually or leverage the Vue Macros plugin.
> Reactivity Transform was an experimental feature, and has been deprecated
英文:
Use the props.probName
pattern to access props in script-setup files. However, in the template section, you must use probName
directly.
So in your case, use props.content
instead of content
to address the issue.
const markedContent = computed(() => {
return marked.parse(props.content);
//return marked.parse(props.content.value);
})
The props
name comes from the definition of your props, where you choose a variable name to hold all properties.
// Here you've defined a variable name (props) that represents all properties
const props = defineProps({
id: Number,
title: String,
create: String,
content: String
});
Access props directly in the setup
If you wish to access props directly (as in the template), you can destruct the props
at the place:
const {content, id, title, create} = defineProps({
id: Number,
title: String,
create: String,
content: String
});
const markedContent = computed(() => {
return marked.parse(content);
})
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.
> You need to always access props as props.x in order to retain reactivity. This means you cannot destructure defineProps because the resulting destructured variables are not reactive and will not update. (link)
To tackle the losing reactivity problem, you need to either use toRef
manually or leverage the Vue Macros plugin.
> Reactivity Transform was an experimental feature, and has been deprecated
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论