首页 > 其他分享 >项目开发中难点-项目使用v-if控制表单/元素/组件显示隐藏,例如调用接口后赋值需重新加载组件,但此时使用this.show=false,赋值后使用this.show=true,组件并未重新加载。

项目开发中难点-项目使用v-if控制表单/元素/组件显示隐藏,例如调用接口后赋值需重新加载组件,但此时使用this.show=false,赋值后使用this.show=true,组件并未重新加载。

时间:2023-09-14 15:27:41浏览次数:35  
标签:nextTick Vue DOM show 更新 组件 message 加载

项目中使用v-if=" show "    控制组件的显示或隐藏,当接口返回后this.show=false,进行赋值,后this.show= true显示 。但是页面没有正常显示,此时使用 this.$nextTick 。

 

一、 $nextTick()概述
1. $nextTick()原理

  • $nextTick() 是 Vue.js 框架中的一个方法,它主要用于 DOM 操作。当我们修改 Vue 组件中的数据时,Vue.js 会在下次事件循环前自动更新视图,并异步执行 $nextTick() 中的回调函数。这个过程可以确保 DOM 已经被更新,以及可以操作到最新的 DOM。

  • 具体来说,当修改了 Vue 组件中的数据时,Vue.js 并不会立即进行视图更新。Vue.js 会将修改的数据记录下来,并在下一次事件循环时才更新视图。而 $nextTick() 方法则是用于等待这个事件循环结束后再执行回调函数。这样可以确保我们操作 DOM 的时候,DOM 已经被 Vue 更新过了。

2. $nextTick()作用

  1.  在下一个更新周期之后执行回调函数。这意味着当 vm.$nextTick() 执行完毕时,DOM 已经被更新。
  2. 在代码执行上下文中延迟回调的执行,直到所有同步的 DOM 更新完成。这可以避免一些异步问题或并发更新(例如修改父组件的数据,然后操作子组件中已更改的 Prop)。
  3. 注意: 在大多数情况下,Vue.js 可以自动处理 DOM 更新并直接渲染到页面上,因此通常情况下不必手动使用 $nextTick() 方法。但对于一些需要在 DOM 更新后执行的操作,比如获取更新后的元素宽高或操作一些插件等,时则很有用。

二、$nextTick()常见应用场景
1. 改变数据后更新DOM元素

<template>
  <div>{{message}}</div>
</template>
<script>
  export default {
    data () {
      return {
        message: 'Hello Vue'
      }
    },
    methods: {
      updateMessage () {
        this.message = 'Updated Message'
        // 在 DOM 更新后操作 DOM
        this.$nextTick(() => {
          // 通过 DOM API 更新文本
          this.$el.textContent = 'DOM Updated!'
        })
      }
    }
  }
</script>

 

2. 获取更新后的DOM尺寸和位置

<template>
  <div ref="box">{{message}}</div>
</template>
<script>
  export default {
    data () {
      return {
        message: 'Hello Vue'
      }
    },
    methods: {
      logBoxInfo () {
        // 获取更新后的 DOM 节点信息
        this.$nextTick(() => {
          const box = this.$refs.box
          console.log(box.offsetWidth, box.offsetHeight)
        })
      }
    }
  }
</script>

 

3. 执行复杂的计算

<template>
  <div>Computed Value: {{computedValue}}</div>
</template>
<script>
  export default {
    data () {
      return {
        items: [1, 2, 3, 4, 5]
      }
    },
    computed: {
      computedValue () {
        // 执行复杂的计算
        const total = this.items.reduce((sum, val) => sum + val, 0)
        // 确保下一个 DOM 周期中更新视图
        this.$nextTick(() => {
          console.log(`Total: ${total}`)
        })
        return total
      }
    }
  }
</script>

 

4. 在父组件中,等待子组件数据更新后再执行操作

// Parent.vue
<template>
  <div>
    <child ref="child"></child>
  </div>
</template>

<script>
import Child from './Child.vue'

export default {
  components: {
    Child
  },
  mounted () {
    // 等待子组件数据更新后再执行操作
    this.$nextTick(() => {
      this.$refs.child.doSomething()
    })
  }
}
</script>

// Child.vue
<template>
  <div>{{message}}</div>
</template>

<script>
export default {
  data () {
    return {
      message: 'Hello'
    }
  },
  methods: {
    doSomething () {
      this.message = 'Updated Message'
    }
  }
}
</script>

 

5. 等待 Vue.js 插件初始化后再执行操作(例如使用 Element UI 组件)

<template>
  <el-date-picker v-model="date"></el-date-picker>
</template>

<script>
export default {
  data () {
    return {
      date: null
    }
  },
  mounted () {
    // 等待 Element UI 组件初始化后再执行操作
    this.$nextTick(() => {
      this.$refs.picker.$el.querySelector('input').focus()
    })
  }
}
</script>

 

6. 监听视图变化并执行相应操作

<template>
  <div>
    <input ref="input" v-model="message">
    <div>Message Length: {{messageLength}}</div>
  </div>
</template>

<script>
export default {
  data () {
    return {
      message: ''
    }
  },
  computed: {
    messageLength () {
      return this.message.length
    }
  },
  methods: {
    focusInput () {
      // 监听视图变化并执行相应操作
      this.$nextTick(() => {
        this.$refs.input.focus()
      })
    }
  },
  mounted () {
    this.focusInput()
  }
}
</script>

 

三、 $nextTick() 与异步更新原理相关问题解析

  • 在 Vue.js 中,数据的改变并不会立即触发 DOM 的更新,而是会放到一个“异步更新队列”中等待处理。Vue.js 会在每一次事件循环(Event Loop)中对异步更新队列进行处理,当上一个事件循环结束后进行 DOM 更新。
  • $nextTick() 方法的作用正是等待上一次事件循环执行完毕,并在下一次事件循环开始时再执行回调函数。这样可以保证回调函数中的 DOM 操作已经被 Vue.js 进行过更新,从而避免了一些潜在的问题。
  • 例如,下面这个示例:
Vue.component('comp', {
  props: ['msg'],
  template: '<div>{{ msg }}</div>'
});

var vm = new Vue({
  el: '#app',
  data: {
    message: 'Hello'
  },
  methods: {
    updateMessage() {
      this.message = 'Hello, World';
      console.log(this.$refs.comp.$el.textContent); // Hello
      this.$nextTick(() => {
        console.log(this.$refs.comp.$el.textContent); // Hello, World
      });
    }
  }
});

 

  • 在 updateMessage 方法中,我们将 message 的值从 “Hello” 修改为 “Hello, Word”,然后打印了子组件 的内容。由于 Vue.js 是异步更新 DOM 的,因此第一个打印结果会是 “Hello” 而不是修改后的 “Hello, World”。但是,使用 $nextTick() 方法可以使得第二个打印结果正确输出 “Hello, World”。

  • 注意:虽然 $nextTick() 方法可以解决异步更新导致的问题,但如果过度使用该方法会导致性能问题。因此,在实际开发中,只有在必要的情况下才应该使用 $nextTick() 方法。

标签:nextTick,Vue,DOM,show,更新,组件,message,加载
From: https://www.cnblogs.com/evident/p/17702543.html

相关文章

  • JS 的6种加载方式
    一、正常模式<scriptsrc="index.js"></script>这种情况下JS会阻塞dom渲染,浏览器必须等待index.js加载和执行完成后才能去做其它事情二、async模式<scriptasyncsrc="index.js"></script>async模式下,它的加载是异步的,JS不会阻塞DOM的渲染,async加载是无顺序......
  • 百度 Web Uploader 文件批量上传组件
    WebUploader是由BaiduWebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件。在现代的浏览器里面能充分发挥HTML5的优势,同时又不摒弃主流IE浏览器,沿用原来的FLASH运行时,兼容IE6+,iOS6+,android4+。两套运行时,同样的调用方式,可供用户任意选用。采用大文件......
  • 【HarmonyOS】如何实现应用内引用HSP模块中ArkUI组件
    ​【关键字】HSP开发、引入HSP模块中ArkUI组件 【写在前面】在使用ArkTS开发HarmonyOS应用时,通常会定义一些公共组件或公共接口功能,此时可以将这些功能封装到HSP模块中,然后通过在HSP模块中导出组件或接口方式在其他模块中引用,可以实现应用内部代码与资源的共享。这里主要讲......
  • 可视化图表组件之股票数据分析应用
    股市是市场经济的必然产物,在一个国家的金融领域之中有着举足轻重的地位。在过去,人们对于市场走势的把握主要依赖于经验和直觉,往往容易受到主观因素的影响,导致决策上出现偏差。如今,通过数据可视化呈现,便可将历年数据和市场情报进行深度挖掘、分析,从中找到规律和趋势,帮助用户做出更......
  • Vue二维码组件
    1.前言该组件依赖qrcode.js与element-ui支持二维码大小配置,点击大图预览该组件以vue文件形式进行封装,需要配置httpVueLoader插件进行引入,其他格式请自行更改源码2.使用方法引入依赖<linkhref="https://cdn.bootcdn.net/ajax/libs/element-ui/2.15.13/theme-chalk/index......
  • 怎么样在表格组件中实现色阶图的效果?
    要在表格组件中实现色阶图的效果,可以通过以下几个步骤实现:确定颜色范围:首先,确定你想要在表格中使用的颜色范围。这个范围可以根据数据的取值范围来确定。配置数据:将数据按照取值范围进行分类,并为每个分类分配对应的颜色。创建表格:使用表格组件(如HTML的<table>元素或其他表格库)......
  • 如何将element-ui中的tab组件默认展示的tab标签数量改掉?
    要将ElementUI中的Tab组件默认展示的标签数量更改,可以使用tab-list属性设置。tab-list属性用于控制默认展示的标签数量。以下是修改Tab组件默认展示标签数量的示例代码:<template><el-tabsv-model="activeTab":tab-list="tabList"><el-tab-panev-for="tabint......
  • Vue 文本字幕组件(Marquee Text Component)
    简介及使用教程Vue文本字幕组件(MarqueeTextComponent)是一个Vue.js的字幕文本组件,具有CSSGPU动画、快速、功能强大等特点。安装Npmnpmivue-marquee-text-componentYarnyarnaddvue-marquee-text-component 使用全局注册importVuefrom'vue'importMa......
  • 《VUE》走马灯组件
    <template><!--走马灯--><divclass="box"><divclass="carousel"><divclass="item"v-for="(v,i)inlist":key="i"@click="open(v)"><img:sr......
  • 09 类加载的内存分析
    packageannotate;publicclassTest09{publicstaticvoidmain(String[]args){System.out.println(newA().a);}}classA{static{a=300;}staticinta=100;}......