解决 Vue 中 input 输入框被赋值后,无法再修改和编辑的问题

目录

需求:

[出现 BUG:](#出现 BUG:)

[Bug 代码复现](#Bug 代码复现)

解决问题:

解决方法1:

解决方法2

[关于 set() 的补充:](#关于 set() 的补充:)


需求:

前段时间,接到了一个需求:在选择框中选中某个下拉菜单时,对应的输入框就得自动填上对应的值。比如在药品名称 中选取了生理盐水, 下栏的药品单位药品用法就会自动填上对应的值

img

img

出现 BUG:

接到这个需求后,我就想到用 v-model 去改变值,但是实现选中菜单自动填写对应的值后,心想用户想修改某个值怎么办?于是我测试时,发现自动填写的值删除不了,重新选取药品名称也无法改变了。那岂不是相当于写死了?

Bug 代码复现

复制代码
<https://zhida.zhihu.com/search?content_id=214634985&content_type=Article&match_order=1&q=el-form-item&zhida_source=entity v-for="(drug, index) in dynamicValidateForm.drugs" :key="index">
    <el-form-item>
        <el-row :gutter="12">
            <el-col :span='11'>
                <https://zhida.zhihu.com/search?content_id=214634985&content_type=Article&match_order=1&q=el-select&zhida_source=entity v-model="drug.name" clearable filterable placeholder="药品名称" @change="selectDrug($event,index)">
                    <https://zhida.zhihu.com/search?content_id=214634985&content_type=Article&match_order=1&q=el-option&zhida_source=entity v-for="item in drugs" :key="item.id" :label="item.药品名称"
                        :value="item.药品名称" >
                    </el-option>
                </el-select>
            </el-col>
            <el-col :span='7'>
                <el-input placeholder="药品剂量" v-model="drug.amount" type='number'>
                </el-input>
            </el-col>
            <el-col :span='4'>
                <el-button @click.prevent="removeDrug(drug)" round type="danger"
                    icon="el-icon-delete">删除</el-button>
            </el-col>
        </el-row>
        <el-row :gutter="12">
            <el-col :span='6'>
                <el-input placeholder="药品单位" v-model="drug.unit">
                </el-input>
            </el-col>
            <el-col :span='6'>
                <el-input placeholder="用法" v-model="drug.method">
                </el-input>
            </el-col>
            <el-col :span='6'>
                <el-input placeholder="频率" v-model="drug.freq">
                </el-input>
            </el-col>
            <el-col :span='6'>
                <el-input placeholder="使用时机" v-model="drug.use">
                </el-input>
            </el-col>
        </el-row>
    </el-form-item>
</el-form-item>

复制代码
data () {
    return {
    	dynamicValidateForm: {
	  domains: [{
	    value: ''
	  }],
	nursings: [],
	drugs: [],
	email: ''
      },
   }
},
methods: {
    selectDrug(e, index) {
         const _this = this;
         this.drugs.forEach(ele => {
             if( ele.药品名称 === e ) {
                 _this.dynamicValidateForm.drugs[index].unit === ele.默认单位)
                 _this.dynamicValidateForm.drugs[index].method === ele.默认用法)
             }
         })
    },
}

解决问题:

然后我查看了官方文档终于明白了:Vue 在实例创建之后添加新的属性到实例上,它不会触发视图更新。

解决方法1:

由此Vue实例创建时,unit 和 method 在dynamicValidateForm中未声明,因此 Vue 就无法对属性执行 getter 和 setter 方法转化过程,以至于dynamicValidateForm 属性不是响应式的,因此无法触发视图更新。所以我们得声明 dynamicValidateForm 这两个对象的属性,如:

复制代码
data () {
    return {
        dynamicValidateForm: {
              domains: [{
                  value: ''
               }],
              nursings: [],
              drugs: [],
              email: ''
              unit: '', // 在 dynamicValidateForm 中声明 unit 
              method: '' // 在 dynamicValidateForm 中声明 method 
         },
    }
},
methods: {
    selectDrug(e, index) {
         const _this = this;
         this.drugs.forEach(ele => {
             if( ele.药品名称 === e ) {
                 _this.dynamicValidateForm.drugs[index].unit === ele.默认单位)
                 _this.dynamicValidateForm.drugs[index].method === ele.默认用法)
             }
         })
    },
}

解决方法2

我们可以使用 Vue 的全局 API : [set](https://zhida.zhihu.com/search?content_id=214634985&content_type=Article&match_order=1&q=%24set&zhida_source=entity "set")()赋值:

复制代码
data () {
    return {
    	dynamicValidateForm: {
	  domains: [{
	    value: ''
	  }],
	nursings: [],
	drugs: [],
	email: ''
      },
   }
},
methods: {
    selectDrug(e, index) {
        const _this = this;
        this.drugs.forEach(ele => {
            if( ele.药品名称 === e ) {
                _this.$set( _this.dynamicValidateForm.drugs[index],'unit', ele.默认单位)
                _this.$set( _this.dynamicValidateForm.drugs[index],'method', ele.默认用法)
            }
        })
    },
}

关于 $set() 的补充:

官方文档:向响应式对象中添加一个 property,并确保这个新 property 同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新 property,因为 Vue 无法探测普通的新增 property (比如 this.myObject.newProperty = 'hi') 注意对象不能是 Vue 实例,或者 Vue 实例的根数据对象。

相关推荐
天若有情6732 分钟前
【C++原创开源】formort.h:一行头文件,实现比JS模板字符串更爽的链式拼接+响应式变量
开发语言·javascript·c++·git·github·开源项目·模版字符串
M ? A36 分钟前
Vue 迁移 React 实战:VuReact 一键自动化转换方案
前端·vue.js·经验分享·react.js·开源·自动化·vureact
yuki_uix36 分钟前
重排、重绘与合成——浏览器渲染性能的底层逻辑
前端·javascript·面试
Burt1 小时前
我的 2026 全栈选型:Vue3 + Elysia + Bun + AlovaJS
vue.js·全栈·bun
止观止1 小时前
拥抱 ESNext:从 TC39 提案到生产环境中的现代 JS
开发语言·javascript·ecmascript·esnext
小锋java12341 小时前
SpringBoot 4 + Spring Security 7 + Vue3 前后端分离项目设计最佳实践
java·vue.js·spring boot
一 乐1 小时前
校园线上招聘|基于springboot + vue校园线上招聘系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·校园线上招聘系统
时寒的笔记1 小时前
js逆向7_案例惠nong网
android·开发语言·javascript
LanceJiang1 小时前
从输入 URL 到页面:一个 Vue 项目的“奇幻漂流”
vue.js
吴声子夜歌2 小时前
ES6——Generator函数详解
前端·javascript·es6