我的组件数量取决于数组数量,所以当我向数组添加新项时,它应该创建新组件.

当创建新组件时,我想获得它的参考,这就是我产生误解的地方.当我试图得到它时,最后添加的组件是undefined.

但是,如果我试图在一段时间后获得参考,它会起作用.我想这是因为异步,但我不确定.

为什么会发生这种情况,是否有办法避免使用setTimeout

<div id="app">
    <button @click="addNewComp">add new component</button>
    <new-comp
        v-for="compId in arr"
        :ref="`components`"
        :index="compId"
        ></new-comp>
    </div>
  <script type="text/x-template " id="compTemplate">
    <h1> I am a component {{index}}</h1>
</script>

Vue.component("newComp",{
  template:"#compTemplate",
  props:['index']
})
new Vue({
  el:"#app",
  data:{
    arr:[1,2,3,4]
  },
  methods:{
    addNewComp:function(){
      let arr = this.arr;
      let components = this.$refs.components;
      arr.push(arr.length+1);
      console.log("sync",components.length);
      console.log("sync",components[components.length-1])
      setTimeout(() => {
        console.log("async",components.length);
        console.log("async",components[components.length-1])
      }, 1);
    }
  }
})

codepen link

推荐答案

ref$refs不是react 性的.

如果要获取更新的值,应该等到下一个渲染周期更新DOM.

你应该使用Vue.nextTick()而不是setTimeout:

new Vue({
  el:"#app",
  data:{
    arr:[1,2,3,4]
  },
  methods:{
    addNewComp:function(){
      let arr = this.arr;
      let components = this.$refs.components;
      arr.push(arr.length+1);
      console.log("sync",components.length);
      console.log("sync",components[components.length-1])
      Vue.nextTick(() => {                                         // changed here
        console.log("async",components.length);
        console.log("async",components[components.length-1])
      });                                                          // changed here
    }
  }
})

这不是"黑客",这是正确的做法.从the official API docs开始:

Vue.nextTick([回调,上下文])

  • Arguments:

    • {Function} [callback]
    • {Object} [context]
  • Usage:

    将回调延迟到下一个DOM更新周期之后执行.

    // modify data
    vm.msg = 'Hello'
    // DOM not updated yet
    Vue.nextTick(function () {
      // DOM updated
    })
    
    // usage as a promise (2.1.0+, see note below)
    Vue.nextTick()
      .then(function () {
        // DOM updated
      })
    

Vue.js相关问答推荐

在VITE-VUE APP-DEV模式上重定向HTTP请求

Vuetify 3 v-radio-group 将模型设置为 null

我如何使用vuejs访问彼此嵌套的json对象

Vue 3 在一个值更改问题后再次重新渲染每一行

在移动版本中使用标准的 v-data-table

带有热重载的 docker 容器上的 Vue.js 应用程序

VueJs this.method 不是函数?如何在 Vuejs 的另一个方法中调用一个方法?

使用 vue.js 的 axios 预检失败错误 301

查看 cli3 启用 CORS

在 SASS 中使用 Vuetify 类

W3C 验证和 Vue 的 HTML 绑定语法

在 Vue.js 中,为什么我们必须在导入组件后导出它们?

正确的 vueJS 方法将props与数据同步

Vue devServer 代理没有帮助,我仍然收到 CORS 错误

交换数组项

Vue.js 的 $emit 和 $dispatch 有什么区别?

如何使用 Vue Test utils 测试输入是否聚焦?

vue-router 如何使用 hash 推送({name:"question"})?

返回 VueJS 方法的Native Code消息

Vue 3 组合 API 数据()函数