vue数据改变页面不刷新? 对vue响应式的理解

vue.jpg

背景

在做项目的时候,需求是一个动态表单的功能

直接上代码

<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的值时,页面的表单没有刷新,表单的输入框无法输入内容。

what2.jpg

分析原因

这是由于Vue2.0响应式原理的核心API是Object.defineProperty()
当vue模板编译器初始化时,object.defineProperty()会一次性深度监听完data实例,对已有的属性转换为getter/setter,但是它无法监听对象属性的新增和删除,如果在实例创建之后添加新的属性到实例上,它不会触发视图更新。所以,当我对updateInfo.data.value进行赋值时,视图不会触发更新

解决办法

办法一:使用Vue.set对新增对象进行赋值

官网Vue.set的介绍

vueSet.png

可见,使用vue.set新增属性时,该属性同样是响应式的

function update(){
    this.updateInfo.data.forEach(item => {
       this.$set(item,'value','')
    )}
}
复制代码

办法二:暴力使用$forceUpdate(),强制渲染组件

官网forceUpdate的介绍

forceUpdate.png

 <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
喜欢就支持一下吧
点赞0 分享