对vue中data的数组push无效

data (){
return {
    keys: []
    }
},
methods: {
    select (key) {
      this.keys.push(key)
      console.log(this.keys)
    }
}

但是在控制台打印发现,并没有直接push,后面添加的将前面添加的覆盖了

clipboard.png
而且在vue-detools中查看keys为空
请问这个是什么原因

<!--specification-->
<template>
<section>
  <div v-for="(types,index) in keys" :key="index">
    <div :class="specStyle">
      <p :class="specTitle">{{types.keyname}}</p>
      <checker
        type="radio"
        :default-item-class="checkDefault"
        :selected-item-class="checkSelected"
        :disabled-item-class="checkDisabled"
        >
        <checker-item v-for="value in types.values"
                      :key ="value.valueid"
                      :value="value.valuename"
                      :disabled="!value.optional"
                      @on-item-click="select(types.keyid, value)">{{value.valuename}}</checker-item>
      </checker>
    </div>
  </div>
</section>
</template>
<script type="text/ecmascript-6">
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()
    }
  }
}
</script>
<style module lang="scss">
.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;
  }
}
</style>
阅读 21.2k
6 个回答

你试试
this.keys = [...this.keys,key]

这里的select方法是怎么触发的

你肯定是又在别的地方有对数组keys进行了操作,建议把完整的代码贴下。

是不是有watch方法监听到keys改变做改动了

浏览器清缓存,ide重启之后好了。。。。。。

vue中更新数组要用set吧,记得大概是

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题