Vue中关于重新渲染组件的方法及总结

目录
  • 重新渲染组件的方法总结
    • 重新加载整个页面
    • 使用forceUpdate
  • 总结

重新渲染组件的方法总结

有时Vue的反应性系统还不够,您只需要重新渲染组件即可。

重新渲染组件有以下几个办法:

  • 可怕的方法:重新加载整个页面
  • 可怕的方法:使用v-if
  • 更好的方法:使用Vue的内置forceUpdate方法
  • 最好的方法:在组件上进行key更改

重新加载整个页面

非常不建议这样做,我们来看下一个办法

v-if指令,该指令仅在组件为true时才渲染。 如果为false,则该组件在DOM中不存在。

下面我们设置它以使其v-if能够正常工作的方式。

在您的template,您将添加v-if指令:

<template>
  <my-component v-if="renderComponent" />
</template>

script您将添加使用以下方法nextTick:

<script>
  export default {
    data() {
      return {
        renderComponent: true,
      };
    },
    methods: {
      forceRerender() {
        // 从 DOM 中删除 my-component 组件
        this.renderComponent = false;
        
        this.$nextTick(() => {
          // 在 DOM 中添加 my-component 组件
          this.renderComponent = true;
        });
      }
    }
  };
</script>

这里发生的事情:

  • 最初renderComponent设置为true,因此my-component组件渲染
  • 在forceRerender中我们立即设置renderComponent为false
  • 停止渲染组件my-component,因为该v-if指令现在的值为false
  • 在nextTick中将renderComponent上设置回true
  • 现在该v-if结果为true,因此我们my-component再次开始渲染

我们必须等到nextTick,否则我们不会看到任何变化。

在Vue中,一个 nextTick 是一个DOM更新周期。Vue将收集在同一 nextTick 中进行的所有更新,在 nextTick 结束时,它将根据这些更新来渲染 DOM 中的内容。如果我们不等到nextTick,我们对renderComponent的更新就会自动取消,什么也不会改变。

其次,当我们第二次渲染时,Vue将创建一个全新的组件。 Vue 将销毁第一个,并创建一个新的,这意味着我们的新my-component将像正常情况一样经历其所有生命周期-created,mounted等。

不过,这并不是一个很好的解决方案,往下看

使用forceUpdate

方法解读:

Vue中,$forceUpdate()的使用

方文档中指出,$forceUpdate具有强制刷新的作用。那在vue框架中,如果data中有一个变量:age,修改他,页面会自动更新。

但如果data中的变量为数组或对象,我们直接去给某个对象或数组添加属性,页面是识别不到的<template>

<p>{{userInfo.name}}</p>
  <button @click="updateName">修改userInfo</button>
</template>
<script>
  data(){
    return{
      userInfo:{name:'小明'}
    }
  },
  methods:{
    updateName(){
      this.userInfo.name='小红'
    }
  }
</script>

在updateName函数中,我们尝试给userInfo对象修改值,发现页面其实并没有变化

那这时候有两种解决方法:

方法一:

methods:{
  updateName(){
    this.userInfo.name='小红'//在此时,确实已经将userInfo对象修改完成
    console.log(this.userInfo.name);//输出结果: 小红
    this.$forceUpdate();//在这里,强制刷新之后,页面的结果变为'小红'
  }
}

$forceUpdate() 这个方法也可以处理 修改for循环 里面 item的属性值,没有渲染出来添加这个方法也生效

方法二:

methods:{
  updateName(){
    this.$set('userInfo',name,'小红');
  }
}

这是解决此问题的两种最佳方法之一,此方法得到Vue的官方支持。

下面是示例:

forceUpdate在组件实例本身以及全局实例上,可以通过两种不同的方式调用

// 全局
import Vue from 'vue';
Vue.forceUpdate();
 
// 使用组件实例
export default {
  methods: {
    methodThatForcesUpdate() {
      // ...
      this.$forceUpdate();
      // ...
    }
  }
}

重要提示:这不会更新您拥有的任何计算属性。调用forceUpdate只会强制重新渲染视图

最好的方法:修改组件的key达到组件重新渲染

在许多情况下,我们需要重新渲染组件。

要正确地做到这一点,我们将提供一个key属性,以便 Vue 知道特定的组件与特定的数据片段相关联。如果key保持不变,则不会更改组件,但是如果key发生更改,Vue 就会知道应该删除旧组件并创建新组件。

我们可以采用这种将key分配给子组件的策略,但是每次想重新渲染组件时,只需更新该key即可。

<template>
  <component-to-re-render :key="componentKey" />
</template>
 
export default {
  data() {
    return {
      componentKey: 0,
    };
  },
  methods: {
    forceRerender() {
      this.componentKey += 1;  
      //this.componentKey += new Date();
    }
  }
}

每次 forceRerender被调用时,我们的componentKey都会改变。

当这种情况发生时,Vue将知道它必须销毁组件并创建一个新组件。

我们得到的是一个子组件,它将重新初始化自身并“重置”其状态。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Vue 组件渲染详情

    目录 前言 全局组件 Vue.extend 组件渲染流程 总结 前言 Vue中组件分为全局组件和局部组件: 全局组件:通过Vue.component(id,definition)方法进行注册,并且可以在任何组件中被访问 局部组件:在组件内的components属性中定义,只能在组件内访问 下面是一个例子: <div id="app"> {{ name }} <my-button></my-button> <aa></aa> &

  • Vue 父子组件的数据传递、修改和更新方法

    父子组件之间的数据关系,我这边将情况具体分成下面4种: 父组件修改子组件的data,并实时更新 子组件通过$emit传递子组件的数据,this.$data指当前组件的data(return{...})里的所有数据, this.$emit('data',this.$data); 之后通过父组件的getinputdata方法来接收数据 @data='getinputdata' 其中的data就是传过来的数据,通过修改这个数据就可以通过父组件实时更新子组件 getinputdata(data) { c

  • 关于vue组件的更新机制 resize() callResize()

    目录 组件的更新机制 resize() callResize() 异步更新机制是如何实现的 组件的更新机制 resize() callResize() 假设有一段代码,通过isCollapse改变触发ref的子组件child触发方法resize(),借着触发callResize()方法. 这是vue组件的更新机制. 子组件是child,父组件是整个界面 ,在父组件上任意触发监听,调用方法resize(): resize()调用callResize(),callResize()把下面的3个方法的r

  • Vue手写实现组件初渲染

    目录 前言 生成虚拟节点 将虚拟节点处理为真实节点 总结 前言 在Vue进行文本编译之后,会得到代码字符串生成的render函数.本文会基于render函数介绍以下内容: 执行render函数生成虚拟节点 通过vm._update方法,将虚拟节点渲染为真实DOM 在vm.$mount方法中,文本编译完成后,要进行组件的挂载,代码如下: Vue.prototype.$mount = function (el) { // text compile code .... mountComponent(v

  • 简单聊一聊Vue3组件更新过程

    目录 前言 副作用渲染函数更新组件的过程 核心逻辑:patch流程 1.处理组件 2.处理普通元素 总结 前言 组件渲染的过程,本质上就是把各种把各种类型的 vnode 渲染成真实 DOM.我们也知道了组件是由模板.组件描述对象和数据构成的,数据的变化会影响组件的变化.组件的渲染过程中创建了一个带副作用的渲染函数,当数据变化的时候就会执行这个渲染函数来触发组件的更新.本文我们就具体分析一下组件的更新过程. 副作用渲染函数更新组件的过程 我们先来回顾一下带副作用渲染函数 setupRenderEf

  • Vue组件的渲染流程详细讲解

    目录 引言与例子 举一个工作中能用到的例子: 实现 extend 执行流程 1. 注册流程(以Vue.component()祖册为例子): 2. 执行流程 3. 渲染流程 总结 注: 本文目的是通过源码方向来讲component组件的渲染流程 引言与例子 在我们创建Vue实例时,是通过new Vue.this._init(options)方法来进行初始化,然后再执行$mount等,那么在组件渲染时,可不可以让组件使用同一套逻辑去处理呢? 答:当然是可以的,需要使用到Vue.extend方法来实现

  • Vue组件更新数据v-model不生效的解决

    目录 组件更新数据v-model不生效 问题描述 原因分析 方法一 方法二 方法三 关于v-model失效的问题 解决办法 组件更新数据v-model不生效 问题描述 在使用Vue双向绑定(v-model)功能时,封装子组件通过Inject功能使用了父组件中的 model 中的属性进行双向绑定,此时在程序中去更新model的某个属性的值,发现子组件没有实时渲染. 原因分析 由于 JavaScript 的限制,Vue 不能检测数组和对象的变化.尽管如此我们还是有一些办法来回避这些限制并保证它们的响

  • Vue组件渲染与更新实现过程浅析

    目录 1. 模板编译 2. 组件渲染和更新 1. 模板编译 Vue的模板编译就是将模板字符串转换为渲染函数的过程.具体来说,当组件的生命周期执行到created和beforeMounted之间时,Vue会将模板(template)编译成渲染函数(render),render函数是一个纯JavaScript函数,由with语句构成,它接收一个Vue组件实例作为参数.当render函数执行时会调用h函数,生成虚拟DOM节点(vnode). 下面给出了常见的template模板以及模板编译后的结果:

  • Vue中关于重新渲染组件的方法及总结

    目录 重新渲染组件的方法总结 重新加载整个页面 使用forceUpdate 总结 重新渲染组件的方法总结 有时Vue的反应性系统还不够,您只需要重新渲染组件即可. 重新渲染组件有以下几个办法: 可怕的方法:重新加载整个页面 可怕的方法:使用v-if 更好的方法:使用Vue的内置forceUpdate方法 最好的方法:在组件上进行key更改 重新加载整个页面 非常不建议这样做,我们来看下一个办法 v-if指令,该指令仅在组件为true时才渲染. 如果为false,则该组件在DOM中不存在. 下面我

  • 在 Vue 中编写 SVG 图标组件的方法

    在考虑了将矢量图标从图标字体迁移到内联 SVG 的 原因 之后,我在 Vue.js 中找到了一个用 SVG 替换图标字体的解决方案,同时仍能保持使用图标字体的灵活性和易用性--能够使用 CSS 轻松改变图标的大小.颜色以及其它属性. 一种流行的方法是使用 v-html 指令和 npm 模块 html-loader 来将 SVG 导入到我们的 Vue 模板中,并在 Vue 的生命周期函数 mounted() 中修改渲染的 <svg> 元素.CSS 样式可以直接应用到 <svg> 元素

  • Vue中正确使用Element-UI组件的方法实例

    一.CDN 目前可以通过 unpkg.com/element-ui获取到最新版本的资源,在页面上引入 js 和 css 文件即可开始使用. <!-- 引入样式 --> <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"> <!-- 引入组件库 --> <script src="https://unp

  • 在vue中封装的弹窗组件使用队列模式实现方法

    前言 由于业务需要,需要在封装的弹窗组件中引入定时器实现倒计时效果,但是如果同时触发两个弹窗,就会导致计时器bug,前一个弹窗的定时器没有被清除,倒计时就会错乱,此时想到的解决办法就是采用队列模式,将每一个需要的弹窗存到队列中,依次的将弹窗展示出来,同时清除定时器 什么是队列 队列(Queue)是先进先出(FIFO, First-In-First-Out)的线性表.在具体应用中通常用链表或者数组来实现.队列只允许在尾部进行插入操作(入队 enqueue),在头部进行删除操作(出队 dequeue

  • React和Vue中监听变量变化的方法

    React 中 本地调试React代码的方法 yarn build 场景 假设有这样一个场景,父组件传递子组件一个A参数,子组件需要监听A参数的变化转换为state. 16之前 在React以前我们可以使用 componentWillReveiveProps 来监听 props 的变换 16之后 在最新版本的React中可以使用新出的 getDerivedStateFromProps 进行props的监听, getDerivedStateFromProps 可以返回 null 或者一个对象,如果

  • vue 中Virtual Dom被创建的方法

    本文将通过解读render函数的源码,来分析vue中的vNode是如何创建的.在vue2.x的版本中,无论是直接书写render函数,还是使用template或el属性,或是使用.vue单文件的形式,最终都需要编译成render函数进行vnode的创建,最终再渲染成真实的DOM. 如果对vue源码的目录还不是很了解,推荐先阅读下 深入vue -- 源码目录和编译过程. 01  render函数 render方法定义在文件 src/core/instance/render.js 中 Vue.pro

  • Vue中实现回车键切换焦点的方法

    几乎在所有浏览器中,都具有 Tab 键切换焦点的功能. 但是任性的用户强烈要求一定要有 Enter 键切换焦点的功能. 为了交付上线拿到钱,我们只好再一次毫无原则性的接受了客户的需求. 在上一代人中,大多都有这种操作习惯.习惯把保存成为编辑,习惯用回车替换 Tab.这是受到微软 excel 荼毒的结果. 起初我以为这个功能很简单,无非就是把 Enter 键的功能转接到 Tab 键上面,分分钟就可以解决掉的问题. 可困难马上就出现了,我发现这条路是走不通的. 我们经常可以主动触发某个事件,比如 e

  • 深入解读VUE中的异步渲染的实现

    接下来在本文里一起看看当数据变化时,从源码层面逐步分析一下触发页面的响应动作之后,如何做渲染到页面上,展示到用户层面的. 同时也会了解在Vue中的异步方法NextTick的源码实现,看一看NextTick方法与浏览器的异步API有何联系. 注意,本文涉及的Vue源码版本为2.6.11. 什么是异步渲染? 这个问题应该先要做一个前提补充,当数据在同步变化的时候,页面订阅的响应操作为什么不会与数据变化完全对应,而是在所有的数据变化操作做完之后,页面才会得到响应,完成页面渲染. 从一个例子体验一下异步

  • vue 2.0封装model组件的方法

    本文介绍了vue 2.0封装model组件的方法,分享给大家,希望对大家有所帮助 单文件组件 使用单文件组件封装model的模板.逻辑和样式,之后就可以在页面中调用此通用组件. 需求 model有两个使用场景: 1.备注/修改密码(简易): 在屏幕中垂直居中 2.添加/修改/展示信息(复杂): 距离屏幕顶部200px,内容过长时可滚动. 3.常规要求(共同点): 标题,关闭icon 点击确定/关闭/遮罩,隐藏model组件 分析上述需求点,得到如下图: wrapper:负责遮盖屏幕 inner:

  • vue中实现在外部调用methods的方法(推荐)

    1.首先定义一个公共的vue组件: var eventHub = new Vue(); 2.在事件当前的组件中,在created中,用$on向公共的组件eventHub传递,translate是自定义的,getCardNum(data)是要在外部调用的方法; eventHub.$on('translate', function (data) { that.getCardNum(data); }); 3.最后在父组件中,注意负组件要用一个变量保存,var vm = new Vue({}): 4.在

随机推荐