不少人不知道可使用这种 key 的方式来对 Vue 组件时行从新渲染!

做者:Michael Thiessen
译者:前端小智
来源:medium
点赞再看,养成习惯

本文 GitHub https://github.com/qq44924588... 上已经收录,更多往期高赞文章的分类,也整理了不少个人文档,和教程资料。欢迎Star和完善,你们面试能够参照考点复习,但愿咱们一块儿有点东西。前端

在某些状况下,咱们必须强制Vue从新渲染组件,若是没有,那可能,你作的业务还不够负责,反正我是常常须要从新渲染组件,哈哈。git

虽然Vue不会自动更新这种状况是相对比较少,可是知道如何在出现这个问题时修复它仍是颇有用的。github

在大多数状况下,此问题根源仍是咱们对 Vue 的响应式理解仍是不够到位。 所以,要尽可能确保咱们要正确使用了Vue。 响应式有时过于棘手,我也常常不知道所措。面试

这节,咱们就来作一些以前不多作过或者没作过的:用 key 来让组件从新渲染。微信

在这篇文章中,会涉及到这几个知识点:工具

  • key 是如何改变组件
  • key 如何与多个子组件一块儿工做
  • 如何强制子组件本身更新

经过改变 key 的值来从新渲染组件

我最喜欢的方法是使用key属性,由于使用key 的方式,Vue 就知道了特定组件与特定数据相关。this

若是 key保持不变,则不会更改组件。 可是,若是key发生更改, Vue 知道它应该删除旧组件并建立一个新组件。spa

下面是一个很是基本的方法:debug

<template>
  <ComponentToReRender
    :key="componentKey"
  />
</template>

<script>
  export default {
    data() {
      return {
        componentKey: 0,
      };
    },
    methods: {
      forceRerender() {
        this.componentKey += 1;
      }
    }
  }
</script>

每次调用forceRerender时,componentKey 的值就会更改。 当componentKey 的值发生改变时,Vue 就知道把ComponentToReRender组件删除并建立一个新组件。调试

这样ComponentToReRender就会从新渲染并重置里面的状态。nice nice!

强制多个子节点进行更新

一样用这种方式也能够用于多个子组件:

<template>
  <div>
    <Child
      :key="key1"
    />
    <Child
      :key="key2"
    />
  </div>
</template>

<script>
  export default {
    data() {
      return {
        key1: 0,
        key2: 0,
      };
    },
    methods: {
      forceRerender(child) {
        if (child === 1) {
          this.key1 += 1;
        } else if( child === 2) {
          this.key2 += 1;
        }
      }
    }
  }
</script>

这里咱们使用了两个单独 key 来分别控制每一个子组件是否从新渲染。将它们分开是为了其中的一个子组件渲染,不会影响到另外另外一个。

但若是但愿两个子组件老是一块儿更新,则可使用相同的 kye。可是,key必须是惟一的,因此下面这种方式,不能工做:

<template>
  <div>
    <Child
      :key="componentKey"
    />
    <Child
      :key="componentKey"
    />
  </div>
</template>

<script>
  export default {
    data() {
      return {
        componentKey: 0,
      };
    },
    methods: {
      forceRerender(child) {
        this.componentKey += 1;
      }
    }
  }
</script>

在这里,仅第一个Child组件会被渲染。 第二个被忽略,由于它具备重复的key 了。

你们都说简历没项目写,我就帮你们找了一个项目,还附赠【搭建教程】

为了解决这个问题,咱们能够基于componentKey为每一个孩子构造一个新key

<template>
  <div>
    <Child
      :key="`${componentKey}-1`"
    />
    <Child
      :key="`${componentKey}-2`"
    />
  </div>
</template>

<script>
  export default {
    data() {
      return {
        componentKey: 0,
      };
    },
    methods: {
      forceRerender(child) {
        this.componentKey += 1;
      }
    }
  }
</script>

由于咱们每次在componentKey后面添加-1-2,因此这两个key始终是惟一的,如今这两个组件都将被从新渲染。

若是是在列表中,则可使用以下方式:

<template>
  <div>
    <Child
      v-for="(item, index) in list"
      :key="`${componentKey}-${index}`"
    />
  </div>
</template>

<script>
  export default {
    data() {
      return {
        list: [
          // ...
        ],
        componentKey: 0,
      };
    },
    methods: {
      forceRerender(child) {
        this.componentKey += 1;
      }
    }
  }
</script>

在这里,咱们将key构造为${componentKey}-${index},所以列表中的每一个项目都会得到惟一的key,只要componentKey一改变,列表中的全部组件将同时从新渲染。

固然,还有更简单的方式,就是用div把列表包裹起来,直接对 div从新更新就好了:

<template>
  <div :key="componentKey">
    <Child
      v-for="item in list"
      :key="item.id"
    />
  </div>
</template>

<script>
  export default {
    data() {
      return {
        list: [
          // ...
        ],
        componentKey: 0,
      };
    },
    methods: {
      forceRerender(child) {
        this.componentKey += 1;
      }
    }
  }
</script>

这中思路能够用在不少地方,能够为咱们摆脱很的困境,你们要牢记起来。

好了,今天就跟你们分享到这里,咱们下期在见,谢谢你们的观看。


代码部署后可能存在的BUG无法实时知道,过后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给你们推荐一个好用的BUG监控工具 Fundebug

原文:https://morioh.com/p/08963bf0...


交流

文章每周持续更新,能够微信搜索「 大迁世界 」第一时间阅读和催更(比博客早一到两篇哟),本文 GitHub https://github.com/qq449245884/xiaozhi 已经收录,整理了不少个人文档,欢迎Star和完善,你们面试能够参照考点复习,另外关注公众号,后台回复福利,便可看到福利,你懂的。

相关文章
相关标签/搜索