我正在尝试重新整理数据列表。我给了每个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,这解决了该问题!
答案 0 :(得分:2)
有些Caveats带有数组
由于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;
}
答案 1 :(得分:1)
这是一个有效的示例:Randomize items fiddle
基本上,我将您的randomize函数的逻辑更改为:
randomize() {
let new_list = []
const old_list = [...this.list] //we don't need to copy, but just to be sure for any future update
while (new_list.length < 4) {
const new_item = old_list[this.get_random_number()]
const exists = new_list.findIndex(item => item.id === new_item.id)
if (!~exists) { //if the new item does not exists in the new randomize list add it
new_list.push(new_item)
}
}
this.list = new_list //update the old list with the new one
},
get_random_number() { //returns a random number from 0 to 3
return Math.floor(Math.random() * 4)
}
答案 2 :(得分:0)
from flask import Flask, render_template
import os
from flask import redirect, url_for, request
from flask_sqlalchemy import SQLAlchemy
import sys
import sqlite3
import datetime
from datetime import date
import csv
app = Flask(__name__)
@app.route("/", methods=["GET", "POST"])
def log():
names = os.getlogin().split(".")[0].title()
error= None
if request.method == "POST":
if request.form["username"]!= os.getlogin() or request.form["password"]!="1234":
error = "Invalid Credentials.Please Try again."
else:
return redirect(url_for("welcome"))
return render_template("login.html", error=error, name=names)
@app.route("/welcome",methods=["GET","POST"])
def welcome():
return render_template("welcome.html")
@app.route("/paymentplan",methods=["GET","POST"])
def paymentplan():
conn = sqlite3.connect("payment_tco.db")
fdate = date.today()
if request.method=="POST":
rxidnumber = request.form["xidnumber"]#
#mytext = request.form["mytexta[]"]# unable to get the value of mytext[]
return render_template("payment.html")
@app.route("/tco",methods=["GET","POST"])
def tco():
return render_template("tco.html")
app.run(debug=True)
在Vue中,数组更改检测有些棘手。大部分就位 数组方法按预期工作(即在您的计算机中进行拼接) $ data.names数组可以使用),但直接关联值(即 $ data.names [0] ='Joe')不会更新反应式渲染 组件。根据您处理服务器端结果的方式, 可能需要考虑本文所述的这些选项 文档:阵列更改检测。
一些需要探索的想法:
使用v-bind:key =“ some_id”更好地使用推送添加 使用Vue.set(example1.items,indexOfItem,newValue)的新元素 (Artokun也提到过)
请注意,它可以工作,但是我很忙,所以我无法对其进行优化,但是它有点太复杂了,我明天再编辑。
答案 3 :(得分:0)
由于Vue.js具有caveats个检测数组修改的功能,可以作为对该问题突出显示的其他答案,因此您可以在随机化数组之前对其进行浅表复制:
randomise: function() {
// make shallow copy
let input = this.list.map(function(item) {
return item;
});
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;
}