vue.js - 数据更改时Vue.js列表不更新
问题描述
我正在尝试重新组织数据列表。我给了每个人li
一个唯一的钥匙,但仍然没有运气!
我以前有过这个工作,就像下面一样,我想我快崩溃了!
let app = new Vue({
el: '#app',
data: {
list: [
{ value: 'item 1', id: '43234r' },
{ value: 'item 2', id: '32rsdf' },
{ value: 'item 3', id: 'fdsfsdf' },
{ value: 'item 4', id: 'sdfg543' }
]
},
methods: {
randomise: function() {
let input = this.list;
for (let i = input.length-1; i >=0; i--) {
let randomIndex = Math.floor(Math.random()*(i+1));
let itemAtIndex = input[randomIndex];
input[randomIndex] = input[i];
input[i] = itemAtIndex;
}
this.list = input;
}
}
});
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<ul>
<li v-for="item in list" :key="item.id">{{ item.value }}</li>
</ul>
<a href="javascript:void(0)" v-on:click="randomise()">Randomize</a>
</div>
编辑:
感谢您的回答,老实说,我提供的示例对于我试图解决的实际问题可能不是最好的。我想我可能已经找到了问题的原因。
我基本上使用与上面类似的逻辑,除了我基于拖放移动一组对象,这适用于普通 HTML。
但是,我在其他地方使用我的拖放组件,其中包含另一个组件,这就是事情似乎分崩离析的地方......
当一个项目在它的数据中移动时,在另一个组件中拥有一个组件会阻止 Vue 重新渲染吗?
下面是我的DraggableBase
组件,我扩展自:
<script>
export default {
data: function() {
return {
dragStartClass: 'drag-start',
dragEnterClass: 'drag-enter',
activeIndex: null
}
},
methods: {
setClass: function(dragStatus) {
switch (dragStatus) {
case 0:
return null;
case 1:
return this.dragStartClass;
case 2:
return this.dragEnterClass;
case 3:
return this.dragStartClass + ' ' + this.dragEnterClass;
}
},
onDragStart: function(event, index) {
event.stopPropagation();
this.activeIndex = index;
this.data.data[index].dragCurrent = true;
this.data.data[index].dragStatus = 3;
},
onDragLeave: function(event, index) {
this.data.data[index].counter--;
if (this.data.data[index].counter !== 0) return;
if (this.data.data[index].dragStatus === 3) {
this.data.data[index].dragStatus = 1;
return;
}
this.data.data[index].dragStatus = 0;
},
onDragEnter: function(event, index) {
this.data.data[index].counter++;
if (this.data.data[index].dragCurrent) {
this.data.data[index].dragStatus = 3;
return;
}
this.data.data[index].dragStatus = 2;
},
onDragOver: function(event, index) {
if (event.preventDefault) {
event.preventDefault();
}
event.dataTransfer.dropEffect = 'move';
return false;
},
onDragEnd: function(event, index) {
this.data.data[index].dragStatus = 0;
this.data.data[index].dragCurrent = false;
},
onDrop: function(event, index) {
if (event.stopPropagation) {
event.stopPropagation();
}
if (this.activeIndex !== index) {
this.data.data = this.array_move(this.data.data, this.activeIndex, index);
}
for (let index in this.data.data) {
if (!this.data.data.hasOwnProperty(index)) continue;
this.data.data[index].dragStatus = 0;
this.data.data[index].counter = 0;
this.data.data[index].dragCurrent = false;
}
return false;
},
array_move: function(arr, old_index, new_index) {
if (new_index >= arr.length) {
let k = new_index - arr.length + 1;
while (k--) {
arr.push(undefined);
}
}
arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
return arr; // for testing
}
}
}
</script>
编辑 2
弄清楚了!以前使用循环索引效果很好,但是这次似乎不是这样!
我更改了v-bind:key
使用数据库 ID,这解决了问题!
解决方案
数组有一些注意事项
由于 JavaScript 的限制,Vue 无法检测到数组的以下更改:
当您直接使用索引设置项目时,例如
vm.items[indexOfItem] = newValue
当您修改数组的长度时,例如
vm.items.length = newLength
为了克服警告 1,以下两个都将完成与 相同的操作
vm.items[indexOfItem] = newValue
,但也会触发反应系统中的状态更新:
Vue.set(vm.items, indexOfItem, newValue)
或者在你的情况下
randomise: function() {
let input = this.list;
for (let i = input.length-1; i >=0; i--) {
let randomIndex = Math.floor(Math.random()*(i+1));
let itemAtIndex = input[randomIndex];
Vue.set(input, randomIndex, input[i]);
Vue.set(input, i, itemAtIndex);
}
this.list = input;
}
推荐阅读
- c++ - Boost::Asio - 我应该让 io_context::run 线程退出吗?
- javascript - 类数组和在打字稿中创建对象
- android - 使用改造将图像从 Android 上传到服务器
- java - 上传文件并自动下载到本地进行访问
- swift - 从完成处理程序中获取数据并进入 tableView
- sql - 如何从 CONCAT 输出自动执行 UPDATE 语句
- agens-graph - 无法访问在 AgensGraph 上创建的图表
- c# - 覆盖 asp.net 核心中的 appsettings 值
- angular - 嵌套选项卡组上的角度材料选项卡组问题(不显示默认选项卡)
- node.js - 为什么在运行 mocha 时分配的变量未定义