vue循环列表视图更新问题

先上个图片
图片描述
循环列表之后每个商品中的计数器加减事件之后第一个商品会触发视图更新 其他的数据会更改但是视图不会更新,试了很多种方法都不行,不明白是哪里除了问题

<template>
    <div>
        <timeline ></timeline>
        <div class="box_1200">
            <h1 class="order_title">商品订购单</h1>
            <div class="order_list">
                <ul class='order_thead clearfix'>
                    <li>
                        <el-checkbox v-model="allChecked" @change="selectAll" :text-color="'#c0000f'" class="radio">全选</el-checkbox>
                    </li>
                    <li class="order_special">
                        <span>商品信息</span>
                    </li>
                    <li>
                        <span>单价</span>
                    </li>
                    <li>
                        <span>数量</span>
                    </li>
                    <li>
                        <span>含税金额</span>
                    </li>
                    <li>
                        <span>重量</span>
                    </li>
                    <li>
                        <span>操作</span>
                    </li>
                </ul>
                <div class="order_line"></div>
                <div class="order_shop_item" v-for="(v,i) in list" :key="i" >
                    <div class="os_check">
                        <el-checkbox v-model="v.isChecked" :text-color="'#c0000f'" class="radio"></el-checkbox>
                    </div>
                    <div class="os_detail clearfix">
                        <img :src="v.goods.goods_mainpic?v.goods.goods_mainpic.split(',')[0]:''">
                        <p>{{v.goods.goods_name}}</p>
                    </div>
                    <div class="os_price">¥{{v.goods.goods_price}}</div>
                    <div class="os_num">
                        <p class="num_box ">
                            <span @click="sub(i)">-</span><input type="type" :index="i" :value="v.num" @input="changeNum" /><span @click="add(i)">+</span>
                          </p>
                    </div>
                    <div class="os_tax">¥{{v.goods.goods_price*v.goods.goods_rules*v.num}}</div>
                    <div>{{v.goods.goods_rules*v.num}}kg</div>
                    <div>删除</div>
                </div>
            </div>
        </div>
        <div class="clear_footbox">
            <div class="box_1200 clearfix">
                <div class="fl cf_checkBox">
                    <el-checkbox v-model="allChecked" @click="selectAll" :text-color="'#c0000f'" class="radio">全选</el-checkbox>
                </div>
                <div class="fr clearfix">
                    <router-link to="/result" class="result_btn fr">去结算</router-link>
                    <div class="fr result_price">
                        <p>&nbsp;&nbsp;&nbsp; 含税总计:<em>¥255</em></p>
                        <p>合计总重量:100000kg</p>
                    </div>
                    <h5 class="fr selected_num">已选中<em> 5 </em>件</h5>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    import timeline from '../components/timeline.vue'
    import {ajax} from '../assets/ajax.js'
    export default {
        name: 'App',
        data(){
            return{
                list:[],
                allChecked:false,//当前是否全选
            }
        },
        mounted(){
            var _this = this;
            ajax({
                url:'/web/shopping_car/list.do',
                data:{},
                success:function(data){
                    var data = data.body;
                    if(data.status==200){
                        data.data.forEach(function(v,i){
                            v.num = 0;
                            _this.$set(v, 'isChecked', false);
                            _this.list = data.data;
                        })
                    }
                }
            })
        },
        components:{timeline},
        methods:{
            changeNum(e){
                this.$set(this.list[e.target.getAttribute('index')],'num',e.target.value);
              },
            add(i){//加减事件
                this.list[i].num+=1;
                //this.$set(this.list[i],'num',this.list[i].num+=1)  试过也不行
            },
            sub(i){//加减事件
                  this.list[i].num>0?this.list[i].num-=1:0;
            },
            selectAll(){//全选
                if (this.allChecked) {
                      this.list.forEach(function (item) {
                          item.isChecked = true;
                      });
                } else {
                      this.list.forEach(function (item) {
                          item.isChecked = false;
                      });
                }
            }
        },
        watch:{
            list:{
                handler(value){
                      var _this = this;
                      var count=0;
                      for(var i=0;i<value.length;i++){
                        if(value[i].isChecked){
                              count++;
                        }
                      }
                      //如果子集全部选中,全选按钮设置选中状态
                      if(count==value.length){
                        _this.allChecked = true;
                      }else{
                        _this.allChecked = false;
                      }
                },
                deep:true
              },
        }
    }

</script>




阅读 3.2k
5 个回答

<input type="type" :index="i" :value="v.num" @input="changeNum" />这里用v-model="v.num"试下

如果是数组数据更改后没有更新视图参考:
Vue深入响应式原理

var vm = new Vue({
  data:{
    a:1
  }
})
// `vm.a` 是响应式的
vm.b = 2
// `vm.b` 是非响应式的
对于已经创建的实例,Vue 不允许动态添加根级别的响应式属性。但是,可以使用 Vue.set(object, propertyName, value) 方法向嵌套对象添加响应式属性。
Vue.set(vm.someObject, 'b', 2)
或
this.$set(this.someObject,'b',2)
data.data.forEach(function(v,i){
    v.num = 0;
    _this.$set(v, 'isChecked', false);
    _this.list = data.data;
})

你这边写得很有问题:

  1. _this.list = data.data;为什么要放循环里面
  2. _this.list = data.data;这边既然是直接改变引用地址,就不需要$set
  3. _this.$set(v, 'isChecked', false); 这个看没懂,data中没有v这个对于的对象吧

猜测你就是想加num与isChecked对应的key-value

data.data.forEach(function(v,i){
    v.num = 0;
    v.isChecked = 0;
})
 _this.list = data.data;

这样不就好了吗?既然采用直接改变地址来添加响应式,那就这样来呗

vm.$set(array|object, key, value)

你的问题很多,不一一说了,直接说答案吧。
this.$set(this.list[i],'num',this.list[i].num+=1) 这个写法是错的,
改成这样:
this.$set(this.list, i, Object.assign({}, this.list[i], {num: this.list[i].num+1}))

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