为什么在 <script> 的主要部分中不知道 onBeforeMount() 中声明的变量?

Why is a variable declared in onBeforeMount() not known in the main section of <script>?

我有一个 Vue3 组件,我在其中使用了预安装挂钩(这是一个精简版,用于解决问题):

<script setup lang="ts">

const hello = () => {
  let a = [... allNotes.value]
}

onBeforeMount(() => {
  let allNotes = ref([])
}

</script>

有了这个,我在定义 a.

的行上得到一个 ReferenceError: allNotes is not defined

为什么会这样?挂载后 allNotes 不为 hello() 所知吗?

为什么要从生命周期钩子内部定义反应变量?如果您希望 allNotes 在组件或脚本的其余部分可用,您只需在 <script setup> 的顶层声明它。请记住,Composition API setup() 函数取代了 beforeCreatecreated 生命周期挂钩,因此 setup() 中定义的任何内容都将随处可用。您可以在 Vue Docs

中阅读更多相关信息

这里的具体问题是 allNotes 仅限于 onBeforeMount() 函数,因此脚本的其余部分不知道。一旦onBeforeMount()被调用完成,它会销毁allNotes,它不再存在。

你可以做到

<script setup>
  const allNotes = ref([])

  const hello = () => {
    allNotes.value.push("Hello")
  }
</script>

为了用选项API说明这一点,你所做的和下面的一样:

export default {
  beforeMount() {
    const allNotes = [];
  },
  methods: {
    hello() {
      this.allNotes.push("Hello!");
    }
  }
}

那是行不通的,因为 allNotes 只存在于 beforeMount() 钩子中。您必须在 data()computed() 属性中声明 allNotes 以便您的 hello() 方法能够使用它。

此外,作为一个小旁注,您应该使用 const 而不是 let 来声明响应式元素。这有点奇怪,因为从技术上讲,您正在更改它的值,但是 Vue 的内部结构使它成为现实,因此您实际上是在更改 Vue 内部存在的它的 copy。因此,您实际上并没有修改原始值,因此 let 是不合适的。