美文网首页Vue.js
Vue data中属性不响应及解决方法

Vue data中属性不响应及解决方法

作者: 简人Lmy | 来源:发表于2019-04-26 18:31 被阅读0次

    现在vue框架用起来虽然很方便,很爽,但是难免也会遇到一些问题,其中新手遇到的data属性更改了但却没有刷新界面,即不响应的问题是比较烦人的,下面我就介绍一下,为vue新手的起步之路扫除一个障碍🙂。

    给vue实例添加属性一般有两种方式。

    1. 直接写在data里面

    data() {
              return {
                       name:''
                     }
            }
    
    1. data中没有age属性

          vm.age = 26
    

    对于这两种情况,第一种的name是响应的,而第二种的age无法响应。为什么呢,我们再解释下是否响应是怎么来的,即vue给属性添加响应关系的过程是怎样的。

    vue会在vue实例初始化的时候对data中的属性执行getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它。

    很明显,第二种的age错过了添加getter/setter转化的时机,所以无法响应。

    不过我相信大多数人遇到问题的都不是这种,而是第一例的另一种情况,我直接上部分代码:

    data()  {
          return {
              person:{}
                 }
    },
    methods:{
          btnPressed():{
              this.person.name = '张三'
         }
    }
    

    这种情况的话,personname确实是被改成了'张三',相信你也log了好几次,但是为什么界面上就是没有更改呢,原因刚才已经说过了,因为这里的name并未添加getter/setter的监测方法,即无法响应,当这个name的值改变的时候,界面上无法进行相应的更改,那有些人可能会说我这个person不是响应的吗?
    没错,person是响应的,但这里的person是个对象,对person添加getter/setter转化方法时,person还没有name这个字段,所以person可以响应,而person.name无法响应。

    推测

    data中的对象类型的属性,如果在data中已写出,就会被添加getter/setter方法进行响应式监测处理,而没有写的则不会,查了很多资料,好像也确实是这个道理,如以下这个例子。

    <template>
      <div id="app">
        <div>{{person.name}}</div>
        <div>{{person.age}}</div>
        <button @click="btnPressed">点击</button>
      </div>
    </template>
    
    <script>
    export default {
      name: 'app',
      data(){
        return {
          person:{name:''}
        }
      },
    
      created(){
        this.person.name = 'liu'
        this.person.age = '100'
      },
      methods:{
        btnPressed(){
          this.person.name = 'zhao'
          this.person.age = '200'
        }
      }
    }
    </script>
    

    根据推测,界面上应该一开始出现'liu''100'两行,但是点击了按钮执行btnPressed之后,第一行会变为'zhao',而第二行不变,还是'100'

    但是!!结果两个值都变了,第二行也变为了'200',之后我又加了各种属性,gender,father等,依然都跟着改变,只要person中有其中一个初始值,它的所有属性就都会变成响应式;
    然而,将person的属性key由'name'改为'names',那么这里的nameage都不会被改变,也就是后面我修改的任意属性值又不是响应式了......不信的可以试试,我这里还没有理解😅,求大神给解释。

    解决方案

    这里首先给出官方的解决方案:

        this.$set(this.person,'name','zhao')
    

    这句话加上之后如果this.personname属性没有setter/getter响应方法,则会添加上,属性为响应式。你可能以为这样就可以了,然而事实还是在执行方法时name属性没有改变🤔,因为我们是把它放在按钮点击方法里的,所以最开始不会执行这个地方,我们找找。

    问题在这里

      created(){
        this.person.name = 'liu'
        this.person.age = '100'
      },
    

    由于这里是第一次给person添加name属性,也没有使用$set方法,所以name这里没有settergetter方法,而后面再用$set方法的时候,由于name属性已存在了,所以$set方法不会再进行setter/getter方法进行响应式监测,这里一定要注意。

    结论:

    还是要细读官方文档,vue作者已经在其中推荐尽量在data初始化中将需要用到的属性都写出来,这样便于维护且可读性更好。
    如果data中某属性对应初始值为{},且依然想要添加响应式属性的话,用以下方法:
          this.$set(this.objectProperty,'key',value)
    
    注意第一次添加该属性一定要用此方法,之后则可以直接用点语法赋值而该属性依然为响应式属性;若第一次用点语法赋值,第二次及以后再用$set方法的话则该属性为非响应式。

    相关文章

      网友评论

        本文标题:Vue data中属性不响应及解决方法

        本文链接:https://www.haomeiwen.com/subject/rhlfnqtx.html