问答

VUE中,动态添加的文本框如何实现数据实时双向绑定?

作者:admin 2021-04-10 我要评论

在线调试地址 http://jsrun.net/Cp3Kp/edit 问题描述 项目中有个功能,通过选择器为商品列表添加商品,为每个新增的商品设置价格,但是以上实现方式造成新增的商...

在说正事之前,我要推荐一个福利:你还在原价购买阿里云、腾讯云、华为云服务器吗?那太亏啦!来这里,新购、升级、续费都打折,能够为您省60%的钱呢!2核4G企业级云服务器低至69元/年,点击进去看看吧>>>)

在线调试地址

http://jsrun.net/Cp3Kp/edit

问题描述

项目中有个功能,通过选择器为商品列表添加商品,为每个新增的商品设置价格,但是以上实现方式造成新增的商品后面的文本框内容输入无法实时更新,在新增商品价格文本框处编辑无效,在原有商品价格文本框处编辑才会生效。为何会出现该现象,如何解决?

主要代码内容

html:

<div id="app">
<template>
  <el-select v-model="value" placeholder="请选择" @change="selectChange">
    <el-option
      v-for="item in goods"
      :key="item.value"
      :label="item.label"
      :value="item">
    </el-option>
  </el-select>
  <div>
    <div v-for="item in goodsPrice" :key="item.value">
        <span>{{item.label}}</span>
        <el-input style="width: 120px" v-model="item.price"/>
    </div>
  </div>
</template>
</div>

js:

data() {
      return {
        // 商品
        goods: [
            {value: '选项1',label: '黄金糕'},
            {value: '选项2',label: '双皮奶'},
            {value: '选项3',label: '蚵仔煎'},
            {value: '选项4',label: '龙须面'},
            {value: '选项5',label: '北京烤'}
        ],
        value: null,
        // 带价商品列表
        goodsPrice: [{value: '选项1',label: '黄金糕',price: 0}]
      }
    },
    methods: {
        // 选中商品,为商品添加价格属性,将带价格属性的商品加入到带价商品列表中
        selectChange(item){
            item.price = 0;
            this.goodsPrice.push(item);
        }
    }
###

vue能够侦测到数组响应式更新的只有七种方法:
(1)push
(2)pop
(3)shift
(4)unshift
(5)splice
(6)sort
(7)reverse
而对于object,能够侦测到object响应式更新则只有两种方法:
(1) vue.$set 设置属性值
(2) vue.$delete 删除属性

楼主的错误在于使用item.price = 0;对对象进行了一个赋值,而这个赋值vue是侦测不到它的变化的,即使用赋值操作不是响应式更新。

所以正确的代码应该是

selectChange(item){
  this.$set(item,'price',0);
  this.goodsPrice.push(item);
}
###
selectChange(item){
            const data = {
              value: item.value,
              label: item.label,
              price: 0
            }
            this.goodsPrice.push(data);
        }

这样试下

###

改成这样

this.goodsPrice.push(JSON.parse(JSON.stringify(item)))

或者其他方式复制或生成一个新的对象

原因就是实际上item指向的是goods内的对象,你添加修改数据时都是用的这个对象
相当于指针操作

###

<el-input style="width: 120px" v-model="item.price"/>

这里绑定的是 price, 你 this.goodsPrice.push(item); 的看上去是 {value: '选项1',label: '黄金糕'}

这样的 price 是无法被监测到的,而且因为你是直接push的原对象,所以导致goodsPrice 里面的也被改变了。

所以你应该把原对象拷贝一下,然后把price字段也加上

selectChange(item){
    this.goodsPrice.push({...item,price:0});
}

版权声明:本文转载自网络,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。本站转载出于传播更多优秀技术知识之目的,如有侵权请联系QQ/微信:153890879删除

相关文章
  • nginx响应速度很慢

    nginx响应速度很慢

  • 点击选中的多选框,会在已选那一栏显示

    点击选中的多选框,会在已选那一栏显示

  • PHP 多态的理解

    PHP 多态的理解

  • 关于C语言中static的问题

    关于C语言中static的问题

腾讯云代理商
海外云服务器