Vue 2.x computed 属性 在其依赖项与内联数据绑定时不会更新
Vue 2.x computed property is not updated when its dependencies are binded with inline data
我在尝试从 Vue 1.0.27 迁移到 Vue 2.0.1 时遇到以下问题。
EDIT 添加了工作 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>
自定义组件。组件:
- 有
tasks
属性 通过 props
- 有一个名为
remaining
的 computed 属性 计算未完成任务的数量
- 有两种方法
toggleCompletedStatus
和 inProgress
自定义组件的代码如下所示
/*****************
* 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
在用户单击任务时不会更新。(即当 task.completed 属性 改变时)
/************
* 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>
感谢任何帮助
这是正常行为,我会让你查看有关道具的迁移指南: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>
如您所见,我在创建的钩子中设置了数据中的任务,以便 Vue 可以监听更改并更新模板。
我在尝试从 Vue 1.0.27 迁移到 Vue 2.0.1 时遇到以下问题。
EDIT 添加了工作 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>
自定义组件。组件:
- 有
tasks
属性 通过 props - 有一个名为
remaining
的 computed 属性 计算未完成任务的数量 - 有两种方法
toggleCompletedStatus
和inProgress
自定义组件的代码如下所示
/*****************
* 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
在用户单击任务时不会更新。(即当 task.completed 属性 改变时)
/************
* 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>
感谢任何帮助
这是正常行为,我会让你查看有关道具的迁移指南: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>
如您所见,我在创建的钩子中设置了数据中的任务,以便 Vue 可以监听更改并更新模板。