我是 Vuejs 新手。做了一些东西,但我不知道这是简单/正确的方法。
我想要什么
我想要数组中的一些日期并在事件中更新它们。首先我尝试了 Vue.set,但没有成功。现在更改我的数组项后:
this.items[index] = val;
this.items.push();
我向数组中推送()任何内容,它都会更新..但有时最后一个项目会被隐藏,不知何故...我认为这个解决方案有点hacky,我怎样才能使它稳定?
简单代码在这里:
new Vue({
el: '#app',
data: {
f: 'DD-MM-YYYY',
items: [
"10-03-2017",
"12-03-2017"
]
},
methods: {
cha: function(index, item, what, count) {
console.log(item + " index > " + index);
val = moment(this.items[index], this.f).add(count, what).format(this.f);
this.items[index] = val;
this.items.push();
console.log("arr length: " + this.items.length);
}
}
})
ul {
list-style-type: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.11/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.min.js"></script>
<div id="app">
<ul>
<li v-for="(index, item) in items">
<br><br>
<button v-on:click="cha(index, item, 'day', -1)">
- day</button>
{{ item }}
<button v-on:click="cha(index, item, 'day', 1)">
+ day</button>
<br><br>
</li>
</ul>
</div>
如果您像这样操作数组,VueJS 无法获取您对状态的更改。
正如常见初学者陷阱中所解释的,您应该使用数组方法,如push、splice或其他方法,并且永远不要像这样修改索引
a[2] = 2
或数组的.length属性。
new Vue({
el: '#app',
data: {
f: 'DD-MM-YYYY',
items: [
"10-03-2017",
"12-03-2017"
]
},
methods: {
cha: function(index, item, what, count) {
console.log(item + " index > " + index);
val = moment(this.items[index], this.f).add(count, what).format(this.f);
this.items.$set(index, val)
console.log("arr length: " + this.items.length);
}
}
})
ul {
list-style-type: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.11/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.min.js"></script>
<div id="app">
<ul>
<li v-for="(index, item) in items">
<br><br>
<button v-on:click="cha(index, item, 'day', -1)">
- day</button> {{ item }}
<button v-on:click="cha(index, item, 'day', 1)">
+ day</button>
<br><br>
</li>
</ul>
</div>
如前所述 - VueJS 根本无法跟踪这些操作(数组元素分配)。 VueJS 使用数组跟踪的所有操作都在here。 但我会再次复制它们:
在开发过程中,您面临一个问题 - 如何忍受这个问题:)。
push()、pop()、shift()、unshift()、sort()和reverse()非常简单,在某些情况下可以帮助你,但主要焦点在于splice(),它可以让你有效地修改 VueJs 将跟踪的数组。 所以我可以分享一些最常用的数组方法。
您需要替换数组中的项目:
// note - findIndex might be replaced with some(), filter(), forEach()
// or any other function/approach if you need
// additional browser support, or you might use a polyfill
const index = this.values.findIndex(item => {
return (replacementItem.id === item.id)
})
this.values.splice(index, 1, replacementItem)
注意:如果您只需要修改项目字段 - 您可以通过以下方式完成:
this.values[index].itemField = newItemFieldValue
这将由 VueJS 跟踪,因为项目(对象)字段将被跟踪。
您需要清空数组:
this.values.splice(0, this.values.length)
实际上你可以用这个函数做更多splice() - w3schools链接 您可以添加多条记录、删除多条记录等
Vue.set() 和 Vue.delete()
Vue.set() 和 Vue.delete() 可用于将字段添加到 UI 版本的数据中。例如,您的对象中需要一些额外的计算数据或标志。您可以为您的对象或对象列表(在循环中)执行此操作:
Vue.set(plan, 'editEnabled', true) //(or this.$set)
并在 Axios 调用之前以相同的格式将编辑后的数据发送回后端:
Vue.delete(plan, 'editEnabled') //(or this.$delete)
另一种解决问题的更轻量级的方法可能是,暂时编辑数组,然后将整个数组分配回您的变量。因为 Vue 不会监视单个项目,它会监视正在更新的整个变量。
所以你这也应该有效:
var tempArray[];
tempArray = this.items;
tempArray[targetPosition] = value;
this.items = tempArray;
这也应该更新你的 DOM。
我来到这里是因为我在使用 vue 时遇到了很多次问题,所以将其留在这里以供将来参考:
这是错误的/没有反应:
this.items = resp.items; // got from api
for(let i = 0; i < this.items.length; i++){
// if you add a new property here, it's not responsive later
this.items[i].selected = false;
}
这是正确的/有反应的:
const items = resp.items; // got from api
for(let i = 0; i < items.length; i++){
// add a new property here
items[i].selected = false;
}
// getters and setters are created for all properties
this.items = items;