为什么我在 nuxt 中的“仅限客户端”组件抱怨“未定义窗口”?

新手上路,请多包涵

我有 Vue SPA,我正在尝试迁移到 nuxt。我在包含在 <client-only> 标签中的组件中使用 vue2leaflet 标签,但仍然收到 nuxt 的错误消息 window is not defined

我知道我可以使用 nuxt-leaflet 或创建一个插件,但这会显着增加供应商捆绑包,我不希望这样。我只想为需要它的组件导入传单插件。有什么办法吗?

 <client-only>
   <map></map>
</client-only>

map 组件:

 <template>
  <div id="map-container">
    <l-map
      style="height: 80%; width: 100%"
      :zoom="zoom"
      :center="center"
      @update:zoom="zoomUpdated"
      @update:center="centerUpdated"
      @update:bounds="boundsUpdated"
    >
      <l-tile-layer :url="url"></l-tile-layer>
    </l-map>
  </div>
</template>

<script>
import {
  LMap,
  LTileLayer,
  LMarker,
  LFeatureGroup,
  LGeoJson,
  LPolyline,
  LPolygon,
  LControlScale
} from 'vue2-leaflet';
import { Icon } from 'leaflet';
import 'leaflet/dist/leaflet.css';

// this part resolve an issue where the markers would not appear
delete Icon.Default.prototype._getIconUrl;

export default {
  name: 'map',
  components: {
    LMap,
    LTileLayer,
    LMarker,
    LFeatureGroup,
    LGeoJson,
    LPolyline,
    LPolygon,
    LControlScale
  },
//...

原文由 yam 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 529
2 个回答

我找到了一种可行的方法,但我不确定如何。在父组件中,将 import 语句移到组件声明中。

 <template>
  <client-only>
    <map/>
  </client-only>
</template>

<script>
export default {
  name: 'parent-component',
  components: {
    Map: () => if(process.client){return import('../components/Map.vue')},
  },
}
</script>

原文由 yam 发布,翻译遵循 CC BY-SA 4.0 许可协议

    <template>
      <client-only>
        <map/>
      </client-only>
    </template>

    <script>
      export default {
        name: 'parent-component',
        components: {
          Map: () =>
            if (process.client) {
              return import ('../components/Map.vue')
            },
        },
      }
    </script>

上面的解决方案对我不起作用。

为什么?这花了我一段时间才发现,所以我希望它能帮助别人。

“问题”是 Nuxt 自动包含“组件”文件夹中的组件,因此您不必手动包含它们。这意味着即使你只在 process.client 上动态加载它,由于这种自动化,它仍然会在服务器端加载它。

我找到了以下两个解决方案:

  1. 将“组件”文件夹重命名为其他名称以停止自动导入,然后使用上面的解决方案 (process.client)。

  2. (和更好的选择 IMO)还有另一个功能可以延迟加载自动加载的组件。为此,请在组件名称前加上“lazy-”前缀。这与 结合将阻止组件在服务器端呈现。

最后你的设置应该是这样的 文件:

 ./components/map.vue
./pages/index.html

索引.html:

     <template>
      <client-only>
        <lazy-map/>
      </client-only>
    </template>
    <script>
    export default {
    }
    </script>

原文由 Flobe 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题