拼接数组不重新渲染table行Vuejs
Splicing array does not re-render table row Vuejs
我有一个用户 table 使用来自 ajax 请求的数据生成。 Table 大致是这样的:Image of Table
当管理员编辑用户的用户名时,我希望用户的行重新呈现更改(特别是用户的名字和姓氏)。
我创造了 table 很好。这些模型工作正常。我的父组件在我的 edit() 方法中接收到编辑后的数据,但我似乎无法使用更改后的数据重新呈现我的目标行。我怎样才能让我的目标行更新?
我尝试了以下但没有用:
- https://vuejs.org/v2/guide/list.html#Caveats
- 我已经为我的行设置了键
- 尝试使用 Vue.set()
设置我的 listOfUsers
- 尝试使用 Vue.set() 代替 splice
下面是我的父 vue 组件(我去掉了不相关的细节):
模板:
<table>
<thead>
<tr>
<th>Name</th>
<th>Email Address</th>
<th>Created</th>
<th>Stat</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="(user, index) in listOfUsers" :key="'row' + user._id">
<td>{{user.first_name + ' ' + user.last_name}}</td>
<td>{{user.email}}</td>
<td>{{user.created}}</td>
<td>
<a v-if="user.confirmed" @click="determineButtonClicked(index, 'confirm')"></a>
<a v-else @click="determineButtonClicked(index, 'unconfirm')"></a>
</td>
<td class="buttonCase">
<a @click="determineButtonClicked(index, 'info')"></a>
<a v-if="user.blocked" @click="determineButtonClicked(index, 'blocked')"></a>
<a v-else @click="determineButtonClicked(index, 'block')"></a>
<a v-if="user.enforce_info === 'required'" @click="determineButtonClicked(index, 'enforceInfoActive')"></a>
<a v-else-if="user.enforce_info === 'done'" @click="determineButtonClicked(index, 'enforceInfoChecked')"></a>
<a v-else @click="determineButtonClicked(index, 'enforceInfo')"></a>
<modal v-if="usersList[index]" @toggleClickedState="setState(index)" @editUser="edit(index, $event)" :id="user._id" :action="action"></modal>
</td>
</tr>
</tbody>
</table>
脚本
<script>
export default {
created: function() {
let self = this;
$.getJSON("/ListOfUsers",
function(data){
self.listOfUsers = data;
});
},
data: function() {
return {
listOfUsers: [],
}
},
methods: {
edit(index, update){
let user = this.listOfUsers[index];
user.firstName = update.firstName;
user.lastName = update.lastName;
// this.listOfUsers.splice(index, 1, user)
this.listOfUsers.$set(index, user)
}
}
}
</script>
感谢您的宝贵时间和帮助!
Vue 没有在您的编辑方法中更新,因为对象本身没有被替换。对象的属性确实会改变,但 Vue 只是在寻找要改变的对象引用。
要强制数组检测实际对象引用的变化,您需要替换对象,而不是修改对象。我不知道你到底想怎么做,但是这个 hacked together fiddle 应该可以证明这个问题,所以你可以解决它:http://jsfiddle.net/tga50ry7/5/
简而言之,如果您将编辑方法更新为如下所示,您应该会在模板中看到重新渲染:
methods: {
edit(index, update){
let currentUser = this.listOfUsers[index];
let newUser = {
first_name: update.firstName,
last_name: update.lastName,
email: currentUser.email,
created: currentUser.created
}
this.listOfUsers.splice(index, 1, newUser)
}
}
你可以这样试试
<script>
export default {
created: function() {
let self = this;
$.getJSON("/ListOfUsers",
function(data){
self.listOfUsers = data;
});
},
data: function() {
return {
listOfUsers: [],
}
},
methods: {
edit(index, update){
let user = this.listOfUsers[index];
user.firstName = update.firstName;
user.lastName = update.lastName;
// this.listOfUsers.splice(index, 1, user)
this.$set(this.listOfUsers,index, user)
}
}
}
</script>
我有一个用户 table 使用来自 ajax 请求的数据生成。 Table 大致是这样的:Image of Table
当管理员编辑用户的用户名时,我希望用户的行重新呈现更改(特别是用户的名字和姓氏)。
我创造了 table 很好。这些模型工作正常。我的父组件在我的 edit() 方法中接收到编辑后的数据,但我似乎无法使用更改后的数据重新呈现我的目标行。我怎样才能让我的目标行更新?
我尝试了以下但没有用:
- https://vuejs.org/v2/guide/list.html#Caveats
- 我已经为我的行设置了键
- 尝试使用 Vue.set() 设置我的 listOfUsers
- 尝试使用 Vue.set() 代替 splice
下面是我的父 vue 组件(我去掉了不相关的细节):
模板:
<table>
<thead>
<tr>
<th>Name</th>
<th>Email Address</th>
<th>Created</th>
<th>Stat</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="(user, index) in listOfUsers" :key="'row' + user._id">
<td>{{user.first_name + ' ' + user.last_name}}</td>
<td>{{user.email}}</td>
<td>{{user.created}}</td>
<td>
<a v-if="user.confirmed" @click="determineButtonClicked(index, 'confirm')"></a>
<a v-else @click="determineButtonClicked(index, 'unconfirm')"></a>
</td>
<td class="buttonCase">
<a @click="determineButtonClicked(index, 'info')"></a>
<a v-if="user.blocked" @click="determineButtonClicked(index, 'blocked')"></a>
<a v-else @click="determineButtonClicked(index, 'block')"></a>
<a v-if="user.enforce_info === 'required'" @click="determineButtonClicked(index, 'enforceInfoActive')"></a>
<a v-else-if="user.enforce_info === 'done'" @click="determineButtonClicked(index, 'enforceInfoChecked')"></a>
<a v-else @click="determineButtonClicked(index, 'enforceInfo')"></a>
<modal v-if="usersList[index]" @toggleClickedState="setState(index)" @editUser="edit(index, $event)" :id="user._id" :action="action"></modal>
</td>
</tr>
</tbody>
</table>
脚本
<script>
export default {
created: function() {
let self = this;
$.getJSON("/ListOfUsers",
function(data){
self.listOfUsers = data;
});
},
data: function() {
return {
listOfUsers: [],
}
},
methods: {
edit(index, update){
let user = this.listOfUsers[index];
user.firstName = update.firstName;
user.lastName = update.lastName;
// this.listOfUsers.splice(index, 1, user)
this.listOfUsers.$set(index, user)
}
}
}
</script>
感谢您的宝贵时间和帮助!
Vue 没有在您的编辑方法中更新,因为对象本身没有被替换。对象的属性确实会改变,但 Vue 只是在寻找要改变的对象引用。
要强制数组检测实际对象引用的变化,您需要替换对象,而不是修改对象。我不知道你到底想怎么做,但是这个 hacked together fiddle 应该可以证明这个问题,所以你可以解决它:http://jsfiddle.net/tga50ry7/5/
简而言之,如果您将编辑方法更新为如下所示,您应该会在模板中看到重新渲染:
methods: {
edit(index, update){
let currentUser = this.listOfUsers[index];
let newUser = {
first_name: update.firstName,
last_name: update.lastName,
email: currentUser.email,
created: currentUser.created
}
this.listOfUsers.splice(index, 1, newUser)
}
}
你可以这样试试
<script>
export default {
created: function() {
let self = this;
$.getJSON("/ListOfUsers",
function(data){
self.listOfUsers = data;
});
},
data: function() {
return {
listOfUsers: [],
}
},
methods: {
edit(index, update){
let user = this.listOfUsers[index];
user.firstName = update.firstName;
user.lastName = update.lastName;
// this.listOfUsers.splice(index, 1, user)
this.$set(this.listOfUsers,index, user)
}
}
}
</script>