背景
在做项目的时候,需求是一个动态表单的功能
直接上代码
<div class="form-wrapper">
<el-form :model="updateInfo" ref="updateInfo" label-width="150px">
<div class="row-wrapper" v-for="(item,index) in updateInfo.data" :key="item.id">
<el-form-item :prop="`data.${index}.key`" :label="item.name">
<el-date-picker v-if="item.key === 'backDate1'" type="datetime" placeholder="选择日期时间" v-model="item.value"/>
<el-select v-else-if="item.key === 'backDouble1'" v-model="item.value">
<el-option v-for="element in dict.accuracy" :key="element.id" :label="element.label" :value="element.id"/>
</el-select>
<el-select v-else-if="item.key === 'backDouble2'" v-model="item.value">
<el-option v-for="element in dict.device_type" :key="element.id" :label="element.label" :value="element.id"/>
</el-select>
<el-input v-else v-model="item.value"/>
</el-form-item>
</div>
</el-form>
</div>
复制代码
data(){
return {
updateInfo : {
data : []
}
}
}
复制代码
function update(){
this.updateInfo.data.forEach(item => {
item.value = ''
)}
}
复制代码
当我在JS中改变item.value的值时,页面的表单没有刷新,表单的输入框无法输入内容。
分析原因
这是由于Vue2.0响应式原理的核心API是Object.defineProperty()
当vue模板编译器初始化时,object.defineProperty()会一次性深度监听完data实例,对已有的属性转换为getter/setter,但是它无法监听对象属性的新增和删除,如果在实例创建之后添加新的属性到实例上,它不会触发视图更新。所以,当我对updateInfo.data.value进行赋值时,视图不会触发更新
解决办法
办法一:使用Vue.set对新增对象进行赋值
官网Vue.set的介绍
可见,使用vue.set新增属性时,该属性同样是响应式的
function update(){
this.updateInfo.data.forEach(item => {
this.$set(item,'value','')
)}
}
复制代码
办法二:暴力使用$forceUpdate(),强制渲染组件
官网forceUpdate的介绍
<el-input @input="forceRender" v-else v-model="item.value"/>
<el-select @change="forceRender" v-else-if="item.key === 'backDouble2'" v-model="item.value">
<el-option v-for="element in dict.device_type" :key="element.id" :label="element.label" :value="element.id"/>
</el-select>
复制代码
function forceRender(){
this.$forceUpdate()
}
复制代码
个人心得
在做vue项目时,深入了解vue响应式原理会能更快的找到问题的原因。
第一次写文章,已经很努力在写了,字不够代码来凑。o(╥﹏╥)o
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END