为什么这个计算属性在我的 Vue 3 应用程序中无法更改?

Why does this computed property fail to change in my Vue 3 app?

提问人:Razvan Zamfir 提问时间:11/1/2023 最后编辑:Razvan Zamfir 更新时间:11/1/2023 访问量:67

问:

我正在从 Vue 的 Options API 过渡到 Composition API,为此,我制作了一个小型的 Todo 应用程序。

在我有:App.vue

<template>
  <div id="app">
    <ErrorMessage
      v-if="!isValid"
      message="The todo body has to be at least 3 characters long"
    />

    <SuccessMessage v-if="allDone" message="You can relex! :)" />

    <p>{{ allDone }}</p>

    <div class="card">
      <Header />
      <List
        :todos="todos"
        @delete-todo="deleteTodo"
        @toggle-todo="toggleTodo"
      />
      <AddTodo @add-todo="addTodo" />
    </div>
  </div>
</template>

<script>
import { ref, computed } from 'vue';
import ErrorMessage from './components/ErrorMessage.vue';
import SuccessMessage from './components/SuccessMessage.vue';
import Header from './components/Header.vue';
import List from './components/List.vue';
import AddTodo from './components/Add.vue';

export default {
  name: 'App',
  components: {
    ErrorMessage,
    SuccessMessage,
    Header,
    List,
    AddTodo,
  },

  setup() {
    const todos = ref([]);
    const isValid = ref(true);
    const allDone = ref(false);

    return { todos, isValid, allDone };
  },

  methods: {
    toggleTodo: function (index) {
      this.todos[index].done = !this.todos[index].done;
    },
    deleteTodo: function (index) {
      if (confirm('Are you sure?')) {
        this.todos.splice(index, 1);
      }
    },
    addTodo: function (text) {
      let newTodo = {
        done: false,
        text: text,
      };

      if (text.length > 2) {
        this.isValid = true;
        this.todos.push(newTodo);
      } else {
        this.isValid = false;
      }
    },
  },

  computed: {
    allDone: function () {
      // Check if there are todos and
      // If all of them are done
      let undoneTodos = this.todos.filter((todo) => todo.done === false);
      return this.todos.length && !undoneTodos.length;
    },
  },
};
</script>

我尝试使用 computed 属性来检查是否有待办事项以及所有待办事项都已完成,在这种情况下,我尝试在警报组件中显示成功消息(“您可以放松!allDone

但是,当满足变量更改的条件时,变量的初始值不会更改。allDone

我做错了什么?

javascript vue.js vuejs3 vue-composition-api

评论


答:

3赞 Moritz Ringler 11/1/2023 #1

从 setup 函数的返回中删除 ,ref 将覆盖 computed 属性。allDone

或者,在安装程序中将其声明为计算属性,并将其从 computed 选项中删除:

setup(){
  const todos = ref([])
  const allDone = computed(() => todos.value.length > 0 && todos.value.every(todo => todo.done))
  ...
  return {todos, allDone, ...}
}