push数组元素不渲染 vue_对vue中data的数组push无效
data (){
return {
keys: []
}
},
methods: {
select (key) {
this.keys.push(key)
console.log(this.keys)
}
}
但是在控制台打印发现,并没有直接push,后面添加的将前面添加的覆盖了
而且在vue-detools中查看keys为空
请问这个是什么原因
{{types.keyname}}
type="radio"
:default-item-class="checkDefault"
:selected-item-class="checkSelected"
:disabled-item-class="checkDisabled"
>
:key ="value.valueid"
:value="value.valuename"
:disabled="!value.optional"
@on-item-click="select(types.keyid, value)">{{value.valuename}}
import { Checker, CheckerItem } from 'vux'
import { sortNumber } from '@/assets/js/mUtils'
export default {
name: 'specification',
props: {
keys: {
type: Array,
required: true
},
details: {
type: Array,
required: true
},
specStyle: {
type: String,
default: function () {
return this.$style.specifications
}
},
specTitle: {
type: String,
default: function () {
return this.$style['specifications-title']
}
},
checkDefault: {
type: String,
default: function () {
return this.$style['checkbox-item']
}
},
checkSelected: {
type: String,
default: function () {
return this.$style['checkbox-item-active']
}
},
checkDisabled: {
type: String,
default: function () {
return this.$style['checkbox-item-disabled']
}
}
},
data () {
return {
selectId: new Map(),
detailArr: [],
id2val: new Map(),
keyids: []
}
},
mounted () { },
methods: {
initSku () {
// 首先从价格组合中获取所有id的排列组合并去重合并库存,生成一个map字典
this.format()
// 此时已经生成一个完整的map字典无重复
// console.log(this.id2val)
/**
* 拿着key去和字典对比
* 1. 先对key遍历,获取到都有哪些规格
* 2. 对规格遍历,获取到具体参数
* 3. 对参数的id去map字典中查询,存在即设置属性有效,不存在设置无效(能否选中根据这个来判断)
*/
this.keys.forEach(ele => {
ele.values.forEach(val => {
this.compare(val)
// 通过上一步的对比之后就可以确定初始化后的哪些为不可选
})
})
},
// 初始化的时候对比分析哪些是不可选的
compare (val) {
// 因为在map字典中的键为字符串,所以这里要把number转换为字符串
let id = val.valueid.toString()
if (this.id2val.has(id)) {
// 判断字典中有该id,说明可选
if (val.optional !== undefined) {
val.optional = true
} else {
this.$set(val, 'optional', true)
}
} else {
// 字典中没有,不可选
if (val.optional !== undefined) {
val.optional = false
} else {
this.$set(val, 'optional', false)
}
}
},
/**
* 选中的时候要实时计算
* keyid是规格大类,
* value是规格的参数
* */
select (keyid, value) {
this.keyids.push(keyid)
console.log(this.keyids)
/**
* 1. value 是规格的参数
* 2. 每一步选中都要去调取库存来动态控制其他按钮的是否可以点击,并且$emit给父组件函数库存和价格
* 3. 首先要判断初始化的是不是可选的,可选的才能点击
*/
if (value.optional) {
let ids = []
/**
* 这里必须使用map,这样在同一个类型下更改选中数值的时候就会自动更新,选中添加,取消选中删除
* 1. 判断点击的id的keyid在选中中有没有,没有直接添加
* 2. 有的话,判断值和点击的一不一样
* 3. 一样的话就是取消选中,直接删除
* 4. 不一样的话就是更改选中
*/
if (this.selectId.has(keyid)) {
if (this.selectId.get(keyid) === value.valueid) {
this.selectId.delete(keyid)
} else {
this.selectId.set(keyid, value.valueid)
}
} else {
this.selectId.set(keyid, value.valueid)
}
// 这里注意.输出的是先value,后key
// 向ids数组中添加进选中的 valueid
this.selectId.forEach((v, k) => {
ids.push(v)
})
// 这里先要对数组的数据进行排序,然后拼接成字符串
ids = ids.sort(sortNumber).join(';')
/**
* 1. 先用点击的id去map中查找其对应的价格等
* 2. 获取到该id的所有可能组合
* 3. 对比所有组合和已有map中的组合,
* 4. 已有map中如果没有,就把这个的值设为不可选
*/
if (ids) { // 取消的时候可能会出现值为空,所以要判断
// 根据点击选中的id去字典中查询到对应的信息,以及相关选项
let msg = this.id2val.get(ids)
if (msg !== undefined) {
// 1. 提交当前选中的状态信息
this.$emit('msg', msg)
// 2. 判断出其余的哪些不可选并设置状态, 如果有这一步就不用判断msg是不是undefined了
this.check(ids, keyid)
} else {
console.log('这个没有货,')
}
} else {
// 取消全部选中的ids为空时,也要提交清空之前选择提交的信息
this.$emit('msg', {count: 1, price: 0, tiaoid: 0})
}
}
},
check (ids, keyid) {
/**
* 1.拿到所有的键和ids对比,其中含有该ids的都应该拿出来
*/
ids = ids.split(';')
let kArr = []
let selectAbout = []
this.id2val.forEach((v, k) => {
kArr.push(k.split(';')) // 生成一个二维数组
})
for (let i = 0; i < kArr.length; i++) {
if (this.isContained(kArr[i], ids)) {
selectAbout.push(`${kArr[i].join(';')}`)
}
}
// console.log(selectAbout)
// 对比
this.keys.forEach(ele => {
ele.values.forEach(val => {
// console.log(val)
// 通过上一步的对比之后就可以确定初始化后的哪些为不可选
this.selectCompare(val, keyid, selectAbout)
})
})
},
selectCompare (val, keyid, selectAbout) {
/** 接收的参数是所有的可选项以及和选中有关的可选项
* 在这里做选中的时候可选处理
* 1. 首先判断选中的keyid,一致的不做改变
* 2. keyid不同的所有有关的的设为可选,其他的设为不可选
*/
console.log(val, keyid, selectAbout)
// selectAbout.forEach(e => {
// console.log(e)
// })
},
// 判断一个数组中是否包含另一个数组的值
isContained (arr1, arr2) {
return arr2.every(val => arr1.includes(val))
},
// 对数据进行整合去重合并
format () {
this.detailArr = this.details
/**
* 1. 首先对价格数据中所有的valueids进行切割
* 2. 对切割后的所有数据进行排列组合
* 3. 排列组合的时候进行去重,如果有重复的则累加库存
* 4. 获取到所有组合的库存后,和keys去对比,库存中没有的keys设置为不可选
*/
for (let i = 0; i < this.detailArr.length; i++) {
/**
* 1. 获取所有的ids
* 2. 对ids进行排列组合
* 3. 对每一个id生成一个对象
* 4. 将这些对象拼成一个数组
* 5. 最终在外围拼成二维数组
*/
let res = this.cutIds(this.detailArr[i].valueids) // 获取到某一价格下所有的id排列组合
let detail = this.detailArr[i] // 获取到某一价格下的所有参数
/*
* 遍历所有的生成一个map,为所有的id组合,对应其库存和价格等信息,并且去重,相同的去重的时候合并库存
*/
for (let i of res) {
if (this.id2val.has(i)) {
let val = this.id2val.get(i).count
val += detail.count
this.id2val.set(i, {
count: val,
price: detail.price,
tiaoid: detail.tiaoid
})
} else {
this.id2val.set(i, {
count: detail.count,
price: detail.price,
tiaoid: detail.tiaoid
})
}
}
}
},
// 将价格中的ids切割,排列组合
cutIds (ids) {
/**
* 1. 对valuesids进行切割
* 2. 对切割的进行穷举排列组合
*/
let idArr = ids.split(';')
// console.log(idArr)
let allKinds = new Set()
for (var a2 = []; a2.push([]) < idArr.length;) {}
var l = Math.pow(2, idArr.length) - 1
for (var i = 1; i <= l; i++) {
var t = []
for (var s = i, k = 0; s > 0; s >>= 1, k++) {
// eslint-disable-next-line
if (s&1 === 1)
t.push(idArr[k])
}
a2[t.length - 1].push(t.join(';'))
}
let set = a2.join(',').split(',')
set.forEach(val => {
allKinds.add(val)
})
return allKinds
}
},
computed: {},
components: {
Checker,
CheckerItem
},
watch: {
// 检测到prop的传值之后再计算生成
details () {
this.initSku()
}
}
}
.specifications {
font-size: 14px;
line-height: 28px;
text-align: left;
box-sizing: border-box;
background-color: #fff;
.specifications-title {
font-weight: bold;
text-align: left;
}
.checkbox-item {
margin: 10px 15px 10px 0;
border: 1px solid #ccc;
padding: 10px 15px;
font-size: 12px;
line-height: 12px;
border-radius: 3px;
font-weight: bold;
}
.checkbox-item-active {
border-color: $m_pink;
background-color: #fff4fa;
color: $m_pink;
}
.checkbox-item-disabled {
border-color: $f_4;
color: $f_4;
}
}
更多推荐
所有评论(0)