Vue.js 单文件组件中的 Mapbox-gl (Quasar-Framework)

Posted

技术标签:

【中文标题】Vue.js 单文件组件中的 Mapbox-gl (Quasar-Framework)【英文标题】:Mapbox-gl in a Vue.js single file component (Quasar-Framework) 【发布时间】:2017-02-01 13:27:48 【问题描述】:

我想在 Quasar Framework (Vue) 单文件组件中实现 Mapbox-gl-js 地图,但我无法正常工作。我在 Googlemaps 上用 Vue 找到了一些代码,在 Mapbox 上用 React 找到了一些东西,并尝试将它们整合在一起。使用下面的地图初始化参数,我可以在 index.html(使用 mapzen 瓦片)中很好地显示地图,但希望它在组件中。

我尝试遵循这个 [https://laracasts.com/discuss/channels/vue/google-maps-and-vue-js](link url),然后针对 Mapbox 进行调整: proj/src/components/maplayout.vue:

<template>
    <quasar-layout>
      <h3>Map</h3>
      <div id='map'></div>
    </quasar-layout>
  </template>

  <script>
  import mapboxgl from '../app'

  export default 
    data () 
      return 
    ,
    create () 
      this.createMap()
    ,
    methods: 
      createMap: function () 
        mapboxgl.accessToken = 'yourmapboxaccestokenkey'
        var simple = 
          'version': 8,
          'sources': 
            'osm': 
              'type': 'vector',
              'tiles': ['https://vector.mapzen.com/osm/all/z/x/y.mvt?api_key=vector-tiles-yourmapzenapikey']
            
          ,
          'layers': [
            'id': 'background',
            'type': 'background',
            'paint': 
              'background-color': '#adddd2'
            
          , 
            'id': 'majorroad',
            'source': 'osm',
            'source-layer': 'roads',
            'type': 'line'
          , 
            'id': 'buildings',
            'type': 'fill',
            'source': 'osm',
            'source-layer': 'buildings'
          ]
        

        // initialize the map
        this.map = new mapboxgl.Map(
          container: 'map',
          style: simple,
          center: [-1.83, -78.183],
          zoom: 5.5
        )
      
    
  
  </script>

  <style>
  </style>

顺便说一句,对于带有 webpack 的 mapbox,您需要特定的加载器,请参阅: [https://mikewilliamson.wordpress.com/2016/02/24/using-mapbox-gl-and-webpack-together/](link网址) 但是因为我之前让 Mapbox 与 Webpack 一起工作(没有 vue),我想我没问题。实际上我在浏览器控制台中没有收到任何错误(但显然没有出现地图)。

在 app.js 文件中我不知道如何处理建议的(可能没有必要,因为 googlemaps 需要回调,不知道关于 mapbox/mapzen?!):

var App = window.App = new Vue (
//code
)

在 Quasar 中,初始化是这样完成的:

Quasar.start(() => 
  Router.start(Vue.extend(), '#quasar-app')
)

我真的不明白...

欢迎任何关于如何使它工作的建议!

【问题讨论】:

【参考方案1】:
<template>
  <div class="hello">
    <div id='map'></div>
  </div>
</template>

<script>
import mapboxgl from 'mapbox-gl';

require('../node_modules/mapbox-gl/dist/mapbox-gl.css');

export default 
  name: 'HelloWorld',
  data() 
    return 
      apiKey:  your api key ,
    ;
  ,
  mounted() 
    this.createMap();
  ,
  methods: 
    createMap() 
      mapboxgl.accessToken = this.apiKey;
      // init the map
      this.map = new mapboxgl.Map(
        container: 'map',
        style: 'mapbox://styles/mapbox/streets-v9',
        minzoom: 1.3,
        center: [-74.0073, 40.7124], // Manhattan
        zoom: 16,
      );

      this.map.addControl(new mapboxgl.Navigation());
    ,
  ,
;
</script>

我想这可能会有所帮助!

【讨论】:

【参考方案2】:

Quasar 基于 Vue2 版本。所以 ready 方法已被弃用,所以使用 mount 方法代替。

【讨论】:

虽然这可能是解决问题的一个有价值的提示,但一个好的答案也可以证明解决方案。请EDIT 提供示例代码来说明您的意思。或者,考虑将其写为评论【参考方案3】:

我很接近。这确实有效:

<template>
  <quasar-layout>
  <h3>Map</h3>
  <div id='map'></div>
  </quasar-layout>
</template>

<script>
import mapboxgl from 'mapbox-gl'
console.dir(mapboxgl)

export default 
  data () 
    return 
  ,
  ready () 
    this.createMap()
  ,
  methods: 
    createMap: function () 
      mapboxgl.accessToken = 'yourmapboxaccestokenkey'
      var simple = 
        'version': 8,
        'sources': 
          'osm': 
            'type': 'vector',
            'tiles': ['https://vector.mapzen.com/osm/all/z/x/y.mvt?api_key=vector-tiles-yourmapzenapikey']
          
        ,
        'layers': [
          'id': 'background',
          'type': 'background',
          'paint': 
            'background-color': '#bbccd2'
          
        ,
          
            'id': 'majorroad',
            'source': 'osm',
            'source-layer': 'roads',
            'type': 'line'
          ,
          
            'id': 'buildings',
            'type': 'fill',
            'source': 'osm',
            'source-layer': 'buildings'
          ]
      

      // init the map
      this.map = new mapboxgl.Map(
        container: 'map',
        style: simple,
        minzoom: 1.3,
        center: [-74.0073, 40.7124], // Manhattan
        zoom: 16
      )

      this.map.addControl(new mapboxgl.Navigation())
    
  

</script>

<style>
</style>

我没有更改我的 Vue 初始化。

【讨论】:

在mounted()中包含this.createMap()会比ready()更合适【参考方案4】:

我注意到的第一件事:您在将 DOM 注入文档之前初始化地图。使用“ready()”代替“created()”方法。

【讨论】:

很高兴得到Quasar Framework创始人本人的回答!我听从你的建议,得到Uncaught TypeError: Cannot set property 'accessToken' of undefined。显然mapboxgl 是未定义的。我确实在 app.js 中导入 mapbox-gl 库,然后 export default mapboxgl 并将其导入 maplayout.vue 中。 检查 app.js 中是否也未定义 mapboxgl。您是否在 app.js 中对 mapboxgl 进行操作?如果没有,直接在你的布局中导入它,而不是通过 app.js 代理它。你有我可以看看的回购吗? 正确导入 mapboxgl 对象后,我得到:未捕获错误:webworkify-webpack:找不到包含工作函数的模块!确保您没有使用 eval 源映射,并且将命名函数传递给 webworkify-webpack!问题在以下回购中:github.com/musicformellons/mapcomponent 我更改了 webpack 配置:devtool: '#cheap-source-map', 并解决了上述错误。地图几乎似乎显示(有一个绿色的地图框画布),除了没有地图细节......不太确定this.map部分但是当我只是在做map时我得到了es-lint错误。

以上是关于Vue.js 单文件组件中的 Mapbox-gl (Quasar-Framework)的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js 加载单文件组件

在 Vue.js 单文件组件中使用 jQuery 插件

如何在后台保持加载一个 vue.js 单文件组件?

vue中创建全局单文件组件/命令

Vue.js 单文件组件导入失败,“undefined has no properties”

不构建单页应用程序时,如何构建 Vue.js 单文件组件并导入它们?