首页 > 解决方案 > 使用 vanilla js append,vue.js 失去了引用

问题描述

我将简化示例。基本上我在一个页面上有多个小部件,我认为最好不要将所有小部件复制到 v-dialog 中,而是使用参考并将它们添加到对话框中并在需要时返回到网格中。问题是当我将我的 html 附加到对话框中并尝试运行 this.$refs vue 丢失了无限加载组件的跟踪... this.$refs 不包含 ref="infinitiveLoading"。如果 some1 可以解释并可能推荐更好的做法.. thx

<div>
  <div id="item_containerTest" ref="item_containerTest">
    <span>Hello world</span>
    <infinite-loading
          ref="infinitiveLoading"
          v-show="items.length !== 0 || this.loading"
          @infinite="infiniteHandler"
        >
          <div slot="no-more"></div>
    </infinite-loading>
  </div>
  <v-dialog v-model="scheduleDialog" id="dialog" ref="dialog"> </v-dialog>
</div>

//忽略 itemID 和 columnID,我需要它们以便在对话框关闭后将项目附加回网格

openFullScreenDialog(itemId, columnId, title){
  itemContainer = document.getElementById(`item_container${title}`);
  dialog = document.getElementById("dialog");
  dialog.append(itemContainer);
}
 

标签: javascripthtmlvue.jsnuxt.jsvuetify.js

解决方案


As Lucero said in the comments, you shouldn't manipulate the DOM with the classic javascript API. The breaks the shadow DOM of Vuejs (i.e. a runtime copy of the current DOM state in memory) and thus, its reactivity and components references.

If you have a content that have to be wrapped in different container depending on a prop for example, you can use slots for this :)

<template>
  <div>
    <div v-if="dialog">
      <slot>
    </div>
    <v-dialog v-else v-model="openDialog">
      <slot>
    </v-dialog>
  </div>
</template>

<script lang="ts">
import { Vue, Component } from 'nuxt-property-decorator'

export default Vue.extends({
  name: 'GridOrDialog',
  props: {
    dialog: { type: Boolean, default: false }
  },
  data() {
    return {
      openDialog: true,
    }
  }
})
</script>

This way, you just have to declare the content once, and it will be on a v-dialog if you sets the prop dialog to true.

<GridOrDialog dialog="isDialogMode">
  <span>Hello world</span>
  <infinite-loading
     ref="infinitiveLoading"
     v-show="items.length !== 0 || this.loading"
     @infinite="infiniteHandler"
  >
    <div slot="no-more"></div>
  </infinite-loading>
</GridOrDialog>

推荐阅读