Vue无法在设置脚本中呈现计算属性时找到变量。

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

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).

&lt;!-- components/Note.vue --&gt;
&lt;script setup&gt;
import { marked } from &quot;marked&quot;;
import { ref, computed } from &quot;vue&quot;;

const props = defineProps({
  id: Number,
  title: String,
  create: String,
  content: String
});

const showContent = ref(false);
const elContent = ref(null);

const scrollHeight = computed(() =&gt; {
  return elContent.value.scrollHeight + &quot;px&quot;;
});

const markedContent = computed(() =&gt; {
  return marked.parse(content.value);
})
&lt;/script&gt;

&lt;template&gt;
  &lt;div class=&quot;row&quot; @click=&quot;showContent=!showContent&quot;&gt;
    &lt;div class=&quot;col-9&quot;&gt;{{ title }}&lt;/div&gt;
    &lt;div class=&quot;col-3&quot;&gt;{{ create }}&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;row&quot; :style=&quot;{height:showContent?scrollHeight:0}&quot; ref=&quot;elContent&quot;&gt;
    &lt;div class=&quot;col&quot;&gt;{{ markedContent }}&lt;/div&gt;
  &lt;/div&gt;
&lt;/template&gt;

Here is the error message

[Vue warn]: Unhandled error during execution of render function (9)
&quot;
&quot;
&quot; at &lt;Note&quot;
&quot;id=27&quot;
&quot;title=\&quot;1Lorem Ipsum\&quot;&quot;
&quot; ...&quot;
&quot;&gt;&quot;
&quot;
&quot;
&quot; at &lt;App&gt;&quot;

[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)
&quot;
&quot;
&quot; at &lt;Note&quot;
&quot;id=27&quot;
&quot;title=\&quot;1Lorem Ipsum\&quot;&quot;
&quot; ...&quot;
&quot;&gt;&quot;
&quot;
&quot;
&quot; at &lt;App&gt;&quot;

Unhandled Promise Rejection: ReferenceError: Can&#39;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.

&lt;!-- This is fine --&gt;
&lt;div class=&quot;row&quot; :style=&quot;{height:showContent?scrollHeight:0}&quot; ref=&quot;elContent&quot;&gt;
  &lt;div class=&quot;col&quot;&gt;{{ marked.parse(content) }}&lt;/div&gt;
&lt;/div&gt;

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(() =&gt; {
  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&#39;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(() =&gt; {
  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

huangapple
  • 本文由 发表于 2023年6月6日 09:05:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/76410833.html
匿名

发表评论

匿名网友

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

确定