目錄
需求:
出現 BUG:
Bug 代碼復現
解決問題:
解決方法1:
解決方法2
關于 $set() 的補充:
需求:
前段時間,接到了一個需求:在選擇框中選中某個下拉菜單時,對應的輸入框就得自動填上對應的值。比如在藥品名稱中選取了生理鹽水,下欄的藥品單位和藥品用法就會自動填上對應的值
img
img
出現 BUG:
接到這個需求后,我就想到用?v-model?去改變值,但是實現選中菜單自動填寫對應的值后,心想用戶想修改某個值怎么辦?于是我測試時,發現自動填寫的值刪除不了,重新選取藥品名稱也無法改變了。那豈不是相當于寫死了?
Bug 代碼復現
<el-form-item v-for="(drug, index) in dynamicValidateForm.drugs" :key="index"><el-form-item><el-row :gutter="12"><el-col :span='11'><el-select v-model="drug.name" clearable filterable placeholder="藥品名稱" @change="selectDrug($event,index)"><el-option 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()賦值:
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 實例的根數據對象。