Vue:触发视图更新的hack

前言

触发视图更新的hack,hack的是什么?hack那些数据改变却没有被vue检测到的更新!那么vue有哪些状况是检测不到数据的变更的? 官方说明的有下面两大类:javascript

  • 数组
  1. 使用下标更新数组元素;
  2. 使用赋值方式改变数组长度;
  3. 使用下标增删数组元素;
  • 对象
  1. 对象的增删
  • 其余
  1. 好比props到子组件的原始属性 …… 具体看另一篇文章: [传送门: Vue:不能检测到Object/Array更新的状况]

正文

那么要怎么hack?!html

原理也很简单~vue

既然vue检测不到数据的变化,那么就强制触发vue去更新!可是vue并无提供这样的接口(我是说统一的接口,不是官方提供的解决方案),若是有提供就不叫hack了对吧!java

是这样的:对于每次vue能够检测到的数据变更,vue都会从新去渲染整个视图上的变更,整个,注意是整个,并非说,data里面那个对象或列表的数据变更了,就仅仅更新对应的视图区域,不是这样的,是整个,ok!因此能够利用这一点!数组

具体的作法就是: 在修改vue检测不到的数据后,再变更一下vue能够检测到的数据,好比更新一下一个随机数app

实践

<div id="app" v-cloak :data-counter="counter">
  <dl>
    <span v-for="(item, index) in arrs">{{ index === 0 ? '' : ', ' }}{{ item }}</span>
  </dl>
  <dl v-for="(item, key) in items">{{key}}: {{item}}</dl>
  <button @click="operate('add')">add</button>
  <button @click="operate('delete')">delete</button>
  <button @click="operate('update')">update</button>
  <button @click="operate('updateArrs')">update arrs</button>
</div>
复制代码
new Vue({
  el: '#app',
  data: {
    useCounter: true,
    counter: 0,
    arrs: [0, 1, 2, 3, 4],
    items: {
      name: 'isaac',
      position: 'coder'
    }
  },
  watch: {
    items: {
      deep: true,
      handler(val, oldVal) {
      	console.log({ val, oldVal });
      }
    }
  },
  methods: {
    env(callback) {
      callback && callback();
      this.useCounter && this.counter++;
    },
    operate(order) {
      if(order === 'add') {
      	this.env(() => {
          this.items.goodAt = 'javascript';
        });
      } else if(order === 'delete') {
        this.env(() => {
          delete this.items.goodAt;
        });
      } else if(order === 'update'){
      	this.items.name = Math.random();
      } else if(order === 'updateArrs') {
      	this.env(() => {
          this.arrs[0] = Math.round(Math.random() * 100);
        });
      }
    }
  }
});
复制代码

正如前言中说的几种状况,都会在以后更新一个data.counter,而data.counter则是能够检测被检测到的!dom

缺点

虽然这样hack确实出发了视图的更新,可是有个缺点:post

  • 对应的watch是检测不到数据的变更!

因此说,最好仍是使用官方提供的解决方案!测试

最后说一句

上面的hack是我在实践中发现的,应该在说debug的时候!由于本身清洗知道数组和对象那些状况下是触发不到视图更新的,可是某次却神奇地更新了视图!而后就开始慢慢地测试~ui

相关文章
相关标签/搜索