【问题标题】:Vue 2.x computed property is not updated when its dependencies are binded with inline dataVue 2.x 计算属性在其依赖项与内联数据绑定时不会更新
【发布时间】:2017-02-11 03:32:29
【问题描述】:

我在尝试从 Vue 1.0.27 迁移到 Vue 2.0.1 时遇到以下问题。

编辑添加了工作JSFidle

情况:

我构建了一个非常简单的应用程序,它获取任务列表(来自模型)并将它们显示在无序列表中,以及未标记为已完成的任务数量(即剩余任务)。 ViewModel 和 Model 的代码如下所示:

 /*************
 *  ViewModel *
 * ***********/

var vm = new Vue({
    el: '#my-app',
    data: data
});


 /*************
 *    Model   *
 * ***********/

var data = {
    my_tasks: [
        {body: "Go to the doctor", completed: false},
        {body: "Go to the bank", completed: false},
        {body: "Go to the zoo", completed: false}
    ],
};

为了显示任务列表,我使用了<task-list> 自定义组件。组件:

  • 通过 props 拥有 tasks 属性
  • 有一个名为remaining计算属性,用于计算未完成任务的数量
  • 有两个方法toggleCompletedStatusinProgress

自定义组件的代码如下所示

 /*****************
 *    Component   *
 * ***************/

Vue.component('task-list', {
    template: '#task-list-template',
    props: ['tasks'],
    computed: {
        remaining: function () {
            return this.tasks.filter(
                this.inProgress
            ).length;
        }
    },
    methods: {
        /**
         * Toggle the completed status of a task
         * @param item
         */
        toggleCompletedStatus: function (item) {
            return item.completed = !item.completed;
        },
        /**
         * Returns true when task is in progress (not completed)
         * @param item
         */
        inProgress: function (item) {
            return !item.completed;
        }

    },
});

<template id="task-list-template">
    <div>
        <h3>My tasks list ( {{ remaining }} )</h3>
        <ul>
            <li v-for="task in tasks" @click="toggleCompletedStatus(task)">
                {{ task.body }}
            </li>
        </ul>
    </div>
</template>

最后在我的视图中,我使用v-bind 指令将组件的任务属性与数据绑定。

 /************
 *    View   * <-- works fine with both Vue 1.X and 2.x
 * **********/

div id="my-app">
    <task-list :tasks="my_tasks"></task-list>
</div>

问题:

如果我尝试内联传递任务列表,则计算属性 remaining 在用户单击任务时不会更新。(即当任务.已完成属性更改)

 /************
 *    View   * <-- works in Vue 1.x, NOT working with Vue 2.x
 * **********/

div id="my-app">
    <task-list :tasks="[{body: "Go to the doctor", completed: false}, {body: "Go to the bank", completed: false}, {body: "Go to the dentist", completed: false}]"></task-list>
</div>

如果我尝试从服务器传递数据,也会出现同样的问题。以下示例在后端使用 Laravel 5.3:

 /************
 *    View   * <-- works in Vue 1.x, NOT working with Vue 2.x
 * **********/

div id="my-app">
    <task-list :tasks="{{$tasks}}"></task-list> <!-- {{$tasks}} are the json encoded data from the server -->
</div>

任何帮助表示赞赏

【问题讨论】:

  • 我还没有接触到 2.0。我很确定您需要在您的 click 函数中添加一个 $emit 事件。

标签: laravel vue.js vuejs2


【解决方案1】:

这是正常行为,我会让您查看有关 props 的迁移指南:http://vuejs.org/guide/migration.html#Prop-Mutation-deprecated4

这里您的示例已更新为与 Vue 2.0 一起使用:

 /*****************
 *    Component   *
 * ***************/

Vue.component('task-list', {
    template: '#task-list-template',
    props: ['tasks-data'],
    data: function () {
    	return { tasks: [] };
    },
    computed: {
        remaining: function () {
            return this.tasks.filter(
                this.inProgress
            ).length;
        }
    },
    created: function () {
    	this.tasks = this.tasksData; // Set default properties
    },
    methods: {
        /**
         * Toggle the completed status of a task
         * @param item
         */
        toggleCompletedStatus: function (item) {
            return item.completed = !item.completed;
        },
        /**
         * Returns true when task is in progress (not completed)
         * @param item
         */
        inProgress: function (item) {
            return !item.completed;
        }
    }
});


 /*************
 *  ViewModel *
 * ***********/

new Vue({
    el: '#my-app'
});
<script src="https://unpkg.com/vue@2.0.1/dist/vue.js"></script>
<div id="my-app">
  <task-list :tasks-data="[{body: 'Hello all', completed: false},{body: 'Goodbye all', completed: false}]"></task-list> 
</div>

<!-- Template for custom component -->
<template id="task-list-template">
    <div>
        <h3>Remaining task {{ remaining }}</h3>
        <ul>
            <li v-for="task in tasks" @click="toggleCompletedStatus(task)">
                {{ task.body }}
            </li>
        </ul>
    </div>
</template>
  

如您所见,我在 created 钩子中的 data 中设置了任务,以便 Vue 可以监听更改并更新模板。

【讨论】:

猜你喜欢
  • 2021-09-06
  • 2018-02-12
  • 1970-01-01
  • 1970-01-01
  • 2011-12-18
  • 2011-03-05
  • 1970-01-01
  • 2012-09-28
  • 1970-01-01
相关资源
最近更新 更多