vue中 $forceUpdate的使用解析

目录
  • 方案分析
  • forceUpdate
    • 本质
    • 实现原理
    • 分析
  • 刷新页面
  • 使用v-if标记
  • key-changing

在vue的开发过程中,数据的绑定通常来说都不用我们操心,例如在​​data​​中有一个​​msg​​的变量,只要修改它,那么在页面上,​​msg​​的内容就会自动发生变化。但是如果对于一个复杂的对象,例如一个对象数组,直接去给数组上某一个元素增加属性,或者直接把数组的​​length​​变成0,vue可能就无法知道发生了改变。这个其实就是考验对于双向绑定的更进一步的理解应用了。
在Vue中,双向绑定属于自动档,然而在特定的情况下,需要手动触发“刷新”操作,目前有四种方案可以选择:

  • 刷新整个页面
  • 使用v-if标记
  • 使用内置的forceUpdate方法
  • 使用key-changing优化组件

方案分析

本次文章主要重点在于分析​​forceUpdate​​这个方法,后续有机会再来分析​​key-changing​​。

forceUpdate

该方案是比较好的一种方式,比如说我们尝试直接给某个​​object​​增加一个属性,发现页面上没有效果;直接将length变成0来清空数组,也没有效果,

关键代码如下:

change: function(index) {
// 增加性格属性
this.girls[idx].character = 'lovely';
},
clear: function() {
// 清空数组
this.girls.length = 0;
}

按照上面的写法没有产生想要的效果,是因为没有按照vue的规范去写,因为文档里面写了,对于深层的,最好用$set方法,这样vue就可以知道发生了变化,同时vue也不建议直接修改length,而是给一个空数组来置空。
如果我们按照vue的规范去写的,是可以实现变化的,

关键代码如下:

change: function(index) {
// 增加性格属性
this.$set(this.girls[idx],'character','lovely')
},
clear: function() {
// 清空数组
this.girls = [];
}

如果我们不想利用​​$set​​去设置,非要按照我们第一种方式去写,可以实现么?可以的,就是利用​​$forceUpdate​​,此时修改了数据,然而页面层没有变动,之后通过日志打印的方式确认数据是否有修改过,之后再确认有没有监听到,用​​$forceUpdate​​就相当于按照最新数据给渲染一下。

关键代码如下:

change: function(index) {
this.girls[idx].character = '男';
this.$forceUpdate();
},
clear: function() {
this.girls.length = 0;
this.$forceUpdate();
}

这种做法实际上并不推荐,官方说如果你现在的场景需要用​​forceUpdate​​方法 ,那么99%是你的操作有问题,如上data里不显示声明对象的属性,之后添加属性时正确的做法时用 ​​$set()​​方法,所以​​forceUpdate​​请慎用。
该同等效果的:window.location.reload()

本质

在vue的官方文档中有说明到这个是一个强制刷新的api,但很少用到,除非是遇到了需要实时响应组件状态的时候

Force the component instance to re-render.

This should be rarely needed given Vue's fully automatic reactivity system. The only cases where you may need it is when you have explicitly created non-reactive component state using advanced reactivity APIs.

实现原理

Vue.prototype.$forceUpdate = function () {
const vm: Component = this
if (vm._watcher) {
vm._watcher.update()
}
}

实例需要重新渲染是在依赖发生变化的时候会通知​​watcher​​,然后通知​​watcher​​来调用​​update​​方法,就是这么简单。

分析

forceUpdate就是重新render

  • 有些变量不在​​ state​​上,但是你又想达到这个变量更新的时候,重新(render),从而渲染虚拟DOM。
  • 注意到这个时候并不是重新加载组件。
  • 结合vue的生命周期,调用​​$forceUpdate​​后只会触发​​beforeUpdate​​和​​updated​​这两个钩子函数,不会触发其他的钩子函数。它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件,即强制更新因某些原因并未渲染到页面的,已经改变的,应该被渲染到页面的数据
  • ​state​​里的某个变量层次太深,更新的时候没有自动触发​​ render​​。

这些时候都可以手动调用 forceUpdate 自动触发 render 。所以建议使用​​ immutable​​来操作​​ state​​ ,​​redux​​ 等​​ flux​​ 架构来管理​​ state​​。

刷新页面

这个方案是挺low的,本质上是刷新页面

this.$router.go(0)

使用v-if标记

如果是刷新某个子组件,则可以通过​​v-if​​指令实现。我们知道,当​​v-if​​的值发生变化时,组件都会被重新渲染一遍。因此,利用​​v-if​​指令的特性,可以达到强制刷新组件的目的。

<template>
<compare v-if="refresh"></compare>
<el-button @click="refreshComp()">刷新comp组件</el-button>
</template>
<script>
import compare from '@/views/compare.vue'
export default {
name: 'parentComp',
data() {
return {
refresh: true
}
},
methods: {
refreshComp() {
// 移除组件
this.refresh = false
// 在组件移除后,重新渲染组件
// this.$nextTick可实现在DOM 状态更新后,执行传入的方法。
this.$nextTick(() => {
this.refresh = true
})
}
}
}
</script>

key-changing

原理很简单,vue使用key标记组件身份,当key改变时就是释放原始组件,重新加载新的组件。

<template>
<div>
<span :key="key"></span>
</div>
</template>
<script>
export default {
data() {
return {
key: 0
}
},
methods: {
handleUpdateClick() {
this.key += 1 // 或者 this.key = new Date();
}
}
}
</script>

到此这篇关于vue中 $forceUpdate的使用解析的文章就介绍到这了,更多相关$forceUpdate解析内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Vue中$forceUpdate()的使用方式

    目录 $forceUpdate()的使用 有两种解决方法 方法一 方法二 关于$forceUpdate的一些理解 $forceUpdate()的使用 在Vue官方文档中指出,$forceUpdate具有强制刷新的作用. 那在vue框架中,如果data中有一个变量:age,修改他,页面会自动更新. 但如果data中的变量为数组或对象,我们直接去给某个对象或数组添加属性,页面是识别不到的 <template> <p>{{userInfo.name}}</p> <but

  • 解决vue this.$forceUpdate() 处理页面刷新问题(v-for循环值刷新等)

    问题描述: 在使用Vue框架开发时,在函数中改变了页面中的某个值,在函数中查看是修改成功了,但在页面中没有及时刷新改变后的值: 解决: 运用 this.$forceUpdate()强制刷新 代码案例 <Select v-model="carSafeLine.insuranceName" placeholder="请选择" class="mulisel option-h" filterable clearable :disabled=&quo

  • vue 里面的 $forceUpdate() 强制实例重新渲染操作

    迫使 Vue 实例重新渲染.注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件. 比如v-for里面数据层次太多, 修改过数据变了,页面没有重新渲染,需手动强制刷新. for(...){ ... } this.$forceUpdate(); 补充知识:VUE项目中使用this.$forceUpdate();解决页面v-for中修改item属性值后页面v-if不改变的问题 页面展示: 实现效果:点击实现列表内容的展开.折叠. 代码: <div class="invoice-lis

  • 详解vue中$nextTick和$forceUpdate的用法

    1.$nextTick vm.$nextTick( [callback] ) this.$nextTick()将回调延迟到下次 DOM 更新循环之后执行,在修改数据之后立即使用它,然后等待 DOM 更新.它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上. 应用场景: 1. 在Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中. 2. 因为在created()钩子函数执行的时候DOM 其实并未

  • vue中 $forceUpdate的使用解析

    目录 方案分析 forceUpdate 本质 实现原理 分析 刷新页面 使用v-if标记 key-changing 在vue的开发过程中,数据的绑定通常来说都不用我们操心,例如在​​data​​中有一个​​msg​​的变量,只要修改它,那么在页面上,​​msg​​的内容就会自动发生变化.但是如果对于一个复杂的对象,例如一个对象数组,直接去给数组上某一个元素增加属性,或者直接把数组的​​length​​变成0,vue可能就无法知道发生了改变.这个其实就是考验对于双向绑定的更进一步的理解应用了.在V

  • 基于Vue实例生命周期(全面解析)

    前面的话 Vue实例在创建时有一系列的初始化步骤,例如建立数据观察,编译模板,创建数据绑定等.在此过程中,我们可以通过一些定义好的生命周期钩子函数来运行业务逻辑.本文将详细介绍Vue实例的生命周期 图示 下图是Vue实例生命周期的图示 解释 接下来,根据提供的生命周期钩子,对Vue实例各个阶段的情况进行详细说明 [beforeCreate] 在实例开始初始化时同步调用.此时数据观测.事件等都尚未初始化 [created] 在实例创建之后调用.此时已完成数据观测.事件方法,但尚未开始DOM编译,即

  • Vue内容分发slot(全面解析)

    前面的话 为了让组件可以组合,需要一种方式来混合父组件的内容与子组件自己的模板.这个过程被称为 内容分发 (或 "transclusion" ).Vue实现了一个内容分发 API,参照了当前 Web 组件规范草案,使用特殊的 <slot> 元素作为原始内容的插槽.本文将详细介绍Vue内容分发slot 编译作用域 在深入内容分发 API 之前,先明确内容在哪个作用域里编译.假定模板为 <child-component> {{ message }} </chi

  • Vue项目中配置pug解析支持

    Vue 的用法没有变化: <template lang="pug"> transition(name="sider") div.hello h3 {{msg}} p(:style="{color:'#000'}", :htmlData="msg") p label button(@click="clickMe") clickTest </template> 要注意的一点是: 标签后面

  • vue封装swiper代码实例解析

    这篇文章主要介绍了vue封装swiper代码实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 data(){ return{ list:[], swiperOption:"", xiding : "", // 轮播高度 SwiperHeight:'' } }, mounted(){ this.onload() // 获取轮播图图片的高度 setTimeout(()=> { // 通过ref获取轮播dom

  • Vue使用NProgress的操作过程解析

    这篇文章主要介绍了Vue使用NProgress的操作过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 NProgress是页面跳转是出现在浏览器顶部的进度条 官网:http://ricostacruz.com/nprogress/ github:https://github.com/rstacruz/nprogress 绿色的进度条就是NProgress实现的效果 安装 $ npm install --save nprogress 或者

  • 解决vue里a标签值解析变量,跳转页面,前面加默认域名端口的问题

    如下所示: let name = 'www.baidu.com/' <a :href="name" rel="external nofollow" > 点击跳转到: localhost:8080/www.baidu.com/ 解决: 写成<a :href="'https//:'+name" rel="external nofollow" > 补充知识:问题:vue.js a标签href里有变量,函数拼接

  • Vue+Java+Base64实现条码解析的示例

    前端部分(Vue + Vant) 引入Vant.使用Vant中的Uploader组件上传文件(支持手机拍照) import Vue from 'vue' import { Uploader } from 'vant' Vue.use(Uploader); 使用Uploader上传组件 <van-uploader> <van-button icon="plus" type="primary" :after-read="afterRead&q

  • Vue中Video标签播放解析后短视频去水印无响应解决

    目录 问题: 情景复现: 链接在Video标签打不开 链接浏览器正常打开 出现的原理 解决方式 前端解决 全局添加标签 Vue单页面添加标签 完美解决: 问题: 发送Ajax请求,请求后端接口解析抖音无水印视频并且展示在页面中,后端已经可以把解析后的访问地址返回,通过浏览器访问该地址也是没有问题的,接着我通过Vue的绑点video的src,预期状态应该是可以被播放的,实际上点击也没反应,查看页面代码也发现video的src已经设置了正确的视频url 情景复现: 前端发送请求到后端接口 我们前端打

随机推荐