如何从 setup() 函数返回反应变量?

时间:2021-06-04 12:02:28

标签: typescript vue.js vuejs3

我正在构建一个小笔记应用程序并在途中学习 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 以使其具有反应性?

1 个答案:

答案 0 :(得分:1)

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

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

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

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