【问题标题】:How to return a reactive variable from a setup() function?如何从 setup() 函数返回反应变量?
【发布时间】:2021-06-04 12:02:28
【问题描述】:

我正在构建一个小笔记应用程序,并且正在学习 Vue3 + Typescript。下面的代码允许动态创建和显示一个笔记数组(我希望我把它修剪得正确,代码下面是一般描述):

<template>
  <q-layout>
    <div
        v-for="note in allNotes"
        class="note q-ma-sm q-gutter-sm"
        :id="note.id"
    >
      <q-editor
          v-model="note.text"
      >
      </q-editor>
    </div>

    <q-page-sticky position="bottom-right" :offset="[18, 18]">
      <q-btn fab icon="add" color="accent" @click="addNewNote"/>
    </q-page-sticky>
  </q-layout>
</template>

<script lang="ts">
import {defineComponent, ref} from 'vue'

export default defineComponent({
  name: 'App',
  components: {},
  setup() {

    // a single note
    interface Note {
      id: number
      creationDate: string
      text: string
      tags: string[]
      deleted: boolean
      isFocused: boolean
    }

    // all the notes in the app
    let allNotes = ref<Note[]>([])

    function addNewNote() {
      const now = new Date()
      allNotes.value.push({
        creationDate: now.toISOString(),
        deleted: false,
        id: now.getTime(),
        tags: [],
        text: "",
        isFocused: false
      })
    }

    function displayedNotes() {
      return allNotes
    }

    return {
      allNotes,
      addNewNote,
    }
  }
});
</script>

<style lang="scss">
</style>

这个想法是allNotes 保存笔记,这些笔记显示在v-for 循环中。

我想做一个小的修改,预计要显示的注释将被过滤,为此我创建了一个方法displayedNotes,它应该简单地返回allNotes(稍后会有一些过滤发生在那里)

<template>
  <q-layout>
    <div
        v-for="note in displayedNotes"
        class="note q-ma-sm q-gutter-sm"
        :id="note.id"
    >
      <q-editor
          v-model="note.text"
      >
      </q-editor>
    </div>

    <q-page-sticky position="bottom-right" :offset="[18, 18]">
      <q-btn fab icon="add" color="accent" @click="addNewNote"/>
    </q-page-sticky>
  </q-layout>
</template>

<script lang="ts">
import {defineComponent, ref} from 'vue'

export default defineComponent({
  name: 'App',
  components: {},
  setup() {

    // a single note
    interface Note {
      id: number
      creationDate: string
      text: string
      tags: string[]
      deleted: boolean
      isFocused: boolean
    }

    // all the notes in the app
    let allNotes = ref<Note[]>([])

    function addNewNote() {
      const now = new Date()
      allNotes.value.push({
        creationDate: now.toISOString(),
        deleted: false,
        id: now.getTime(),
        tags: [],
        text: "",
        isFocused: false
      })
    }

    function displayedNotes() {
      return allNotes
    }

    return {
      allNotes,
      displayedNotes,
      addNewNote,
    }
  }
});
</script>

<style lang="scss">
</style>

区别是

  • v-for 迭代 displayedNotes 而不是 allNotes
  • displayedNotes() 是一种新方法。

最终结果是什么都没有显示,displayedNotes 被创建,但当allNotes 增长时为空。

我应该如何返回 displayedNotes 以使其具有反应性?

【问题讨论】:

    标签: typescript vue.js vuejs3


    【解决方案1】:

    你应该像这样创建一个计算属性:

    const filteredNotes = computed(() => displayedNotes())
    

    在这种情况下,displayedNotes() 稍后可能会被重命名,并且在该函数中您可以添加过滤逻辑。如果您的 allNotes 然后发生更改,则计算中的该函数将被再次调用并返回新的 filteredNotes

    您现在要做的只是将filteredNotes 添加到您的返回对象中,并在您的v-for 循环中使用它而不是allNotes

    【讨论】:

    • 还可以了解您的代码中哪些地方不能正常工作。可能有两件事 1. 在您的v-for 电话中,您需要拨打displayedNotes() 我猜。 2. 你返回的是allNotes,这是一个ref。所以你实际上有一个Proxy,你只返回那个。您需要将.value 添加到您的return allNotes
    • 谢谢。首先,我忘记了computed() :/。谢谢你提醒我。然后我意识到我对.value 部分不太了解(我知道,只是不太确定它应该在哪里真正使用) - 我会继续阅读。最后随着更改,一切正常 :) 谢谢
    猜你喜欢
    • 1970-01-01
    • 2010-09-07
    • 2016-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-12
    相关资源
    最近更新 更多