这是我最近利用vue+elementUI+axios开发的一个vue项目,这是一个简单的项目 ,但也是让我收获很多,借此跟大家分享对于vue项目开发的一些经验所得
本系统没有什么特别的亮点所在,但也是有许多数据进行格式化,这个也是相对比较复杂,
解决的问题:
1.vue添加新的属性视图不会更新
2.不统一的表格动态添加列
3.对象赋值只是统一指针指向
4.数组的内容重复判断
5.对输入表单的内容进行权重为1 的判断
1. vue添加新的属性视图不会更新
当我使用"this.key = value"的方式进行对对象的属性的更显,效果不尽人意,虽然发现值是在改变,但就是不会产生,于是乎翻开vue的文档寻找一波,最后才发现深入响应式原理中有写到
由于 JavaScript 的限制,Vue 不能检测以下数组的变动:
当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue
当你修改数组的长度时,例如:vm.items.length = newLength
举个例子:
var vm = new Vue({
data: {
items: ['a', 'b', 'c']
}
})
vm.items[1] = 'x' // 不是响应性的
vm.items.length = 2 // 不是响应性的
为了解决第一类问题,以下两种方式都可以实现和 vm.items[indexOfItem] = newValue
相同的效果,同时也将在响应式系统内触发状态更新:
// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
你也可以使用 vm.$set 实例方法,该方法是全局方法 Vue.set 的一个别名:
vm.$set(vm.items, indexOfItem, newValue)
为了解决第二类问题,你可以使用 splice:
vm.items.splice(newLength)
还是由于 JavaScript 的限制,Vue 不能检测对象属性的添加或删除:
var vm = new Vue({
data: {
a: 1
}
})
// `vm.a` 现在是响应式的
vm.b = 2
// `vm.b` 不是响应式的
对于已经创建的实例,Vue 不允许动态添加根级别的响应式属性。但是,可以使用 Vue.set(object, propertyName, value)
方法向嵌套对象添加响应式属性。例如,对于:
var vm = new Vue({
data: {
userProfile: {
name: 'Anika'
}
}
})
你可以添加一个新的 age 属性到嵌套的 userProfile 对象:
Vue.set(vm.userProfile, 'age', 27)
你还可以使用 vm.$set 实例方法,它只是全局 Vue.set 的别名:
vm.$set(vm.userProfile, 'age', 27)
有时你可能需要为已有对象赋值多个新属性,比如使用 Object.assign() 或 _.extend()。在这种情况下,你应该用两个对象的属性创建一个新的对象。所以,如果你想添加新的响应式属性,不要像这样:
Object.assign(vm.userProfile, {
age: 27,
favoriteColor: 'Vue Green'
})
你应该这样做:
vm.userProfile = Object.assign({}, vm.userProfile, {
age: 27,
favoriteColor: 'Vue Green'
})
本问题的解决办法
用Vue.set(Object,‘属性名’,默认值)这样设定就好了
this.object.forEach(function (quotadata) {
Vue.set(quotadata, 'yAxisIndex', 0)
})
or
this.$set(this.object,"key","value")
这样就木有问题了
2.不统一的表格动态添加列
实现的业务逻辑是通过后台发出的一串json对象,转化为一份表格数据,但是由于他的数据是不是每次都是统一的,表格的列数需要动态添加。我知道可以通过JS可以较为复杂解决这个问题。
但我使用element-ui框架,可以通过一个简单的办法进行调用,动态生成表头,,它表格组件可以支持动态添加表头,实现方法如下,
1、template
<el-table style="width: 100%" border :data="tableData">
<template v-for="(item,index) in tableHead">
<el-table-column :prop="item.column_name" :label="item.column_comment" :key="index" v-if="item.column_name != 'id'"></el-table-column>
</template>
</el-table>
2、script
//javascript
// 表头数据
tableHead:[
{
column_name: "column_name",column_comment:"姓名"
},
{
column_name: "column_age",column_comment:"年龄"
},
{
column_name: "column_sex",column_comment:"性别"
}
],
// 表格数据
tableData: [{
column_age: '3',
column_name: '鞠婧祎',
column_sex: '女'
},
{
column_age: '25',
column_name: '魏大勋',
column_sex: '男'
},
{
column_age: '18',
column_name: '关晓彤',
column_sex: '女'
}],
3.对象赋值只是统一指针指向
项目开发中,实现的业务逻辑,在一个for循环中,获得一个对象,并将这个对象发送到服务器上,并将这个对象重新,再进行上传,但每次发现上传 的接口,都是一样的对象,我刚开始我还以为是闭包的问题,并将接口转为立即执行函数,但并没有成功,后来通过一段时间的研究,并不是这个问题,问题的原因在于:执行异步函数,会将函数的内容传入到堆栈中去,当同步函数全部执行完,才可以轮到堆栈中的代码,但此时的对象,已经被后面对象赋值进行更改了指针指向的内容了,这个就是问题的关键。‘
解决问题:将对象进行深层次拷贝,而不是简单的赋值(指针统一指向)
解决方法:
方法一
利用JSON.parse()和JSON.stringify() 对对象进行深层拷贝
var data={a:1,b:2,c:3,d:4};
var newData=JSON.parse(JSON.stringify(data));
newData.a="1111111"
console.log(newData,data)
方法二
利用JQuery 扩展属性进行拷贝
1 var data={a:1,b:2,c:3,d:4};
2 var newData= $.extend(true,{},data);;
3 newData.a="1111111"
4 console.log(newData,data)
4.数组的内容重复判断
业务逻辑:用户进行表单输入,但是不可以选择同一门课程多次,需要他选择的唯一id,进行判断。
解决办法
方法一:
function isRepeat() {
var ary = new Array("111", "22", "33", "111");
var s = ary.join(",") + ",";
for (var i = 0; i < ary.length; i++) {
if (s.replace(ary[i] + ",", "").indexOf(ary[i] + ",") > -1) {
alert("数组中有重复元素:" + ary[i]);
break;
}
}
}
方法二:
function isRepeat() {
var ary = new Array("111", "22", "33", "111");
var nary = ary.sort();
for (var i = 0; i < ary.length; i++) {
if (nary[i] == nary[i + 1]) {
alert("数组重复内容:" + nary[i]);
}
}
}
方法三:
function isRepeat(arr) {
var hash = {};
for (var i in arr) {
if (hash[arr[i]]){
return true;
}
hash[arr[i]] = true;
}
return false;
}
5.对输入表单的内容进行权重为1 的判断
代码如下:
(权重可为小数点制,也可百分制,或者百分比制)
function adjustWeight(array,target) {
var weightSum = 0;
var re = /^-?(\d+\.?\d+?)%$/;
var len = array.length;
for (var i = 0; i < len; i++) {
var weight = array[i][target];
if (re.test(weight)) {
var str = weight.replace("%", "");
weight = str / 100;
} else {
weight = parseFloat(weight);
}
weightSum += weight;
}
if (weightSum == 1||weightSum==100) {
return true;
} else {
return false;
}
}