我目前正在使用传单地图(使用vue2leaflet)。
我所做的几乎是标准的:
所以基本上我的 Map.vue 会调用地图:
<v-map ref="map" :zoom="zoom" :center="center">
<v-tilelayer url="http://{s}.tile.osm.org/{z}/{x}/{y}.png"></v-tilelayer>
<v-marker-cluster :options="clusterOptions">
<v-marker v-for="(marker, index) in markers"
:key="index"
:lat-lng="makeCoords(marker.location.lat, marker.location.lng)"
v-on:l-click="showSpot(marker._id, marker.slug, marker.location.lat, marker.location.lng)">
</v-marker>
</v-marker-cluster>
</v-map>
标记来自商店($ store.map.markers):
computed: {
markers () {
return this.$store.state.map.markers
}
}
所以在同一个模板中,如果我想获得对地图的引用,我只需要这样做:
this.$refs.map
但我需要从另一个文件中做同样的事情(让我们说&#34; AddMarker.vue &#34;,以便在地图上放置新标记,使用这种方法:
L.marker([datas.location.lat, datas.location.lng]).addTo(mymap);
其中&#34; mymap&#34;应该是 Map.vue
中定义的对象当然,由于地图不在同一个文件中,这个。$ refs.map 会导致&#34; undefined&#34;。
我尝试在商店中添加地图引用,但它不起作用并触发错误(调用堆栈),我想它不会存储组件。
我试图在商店中提交新标记,但地图不会神奇地适应并添加它。我想我真的需要为此调用addTo()方法。
这是商店:
export const state = () => ({
markers: null
})
export const mutations = {
setMarkers(state, markers) {
state.markers = markers
},
addMarker(state, marker) {
state.markers.push(marker)
}
}
export const actions = {
async init({ commit }) {
let { data } = await this.$axios.get(process.env.api.spots)
commit('setMarkers', data)
}
}
以下我称之为突变:
that.$store.commit('map/addMarker', {
title: values.title,
description: values.description,
location: {
city: that.$store.state.position.infos.city,
country: that.$store.state.position.infos.country,
lat: that.$store.state.position.coords.lat,
lng: that.$store.state.position.coords.lng
}
});
标记在商店中完美添加,但地图上没有任何内容。
如果有人知道如何处理这个问题? 谢谢!
答案 0 :(得分:2)
您的实际问题是:“如何向markers
添加其他标记?”如果将markers
定义为基于商店的计算,则需要在商店中添加标记。
Vue.component('v-map', Vue2Leaflet.Map);
Vue.component('v-tilelayer', Vue2Leaflet.TileLayer);
Vue.component('v-marker', Vue2Leaflet.Marker);
const store = new Vuex.Store({
state: {
markers: [
[47.42, -1.25],
[47.41, -1.21],
[47.43, -1.22]
].map(p => L.latLng(...p))
},
mutations: {
addMarker(state, payload) {
state.markers.push(payload);
}
},
actions: {
addMarker({
commit
}, payload) {
commit('addMarker', payload)
}
}
})
const v = new Vue({
el: '#app',
store,
data() {
return {
zoom: 13,
center: [47.413220, -1.219482],
url: 'http://{s}.tile.osm.org/{z}/{x}/{y}.png',
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
}
},
computed: {
markers() {
return this.$store.state.markers;
}
}
});
setTimeout(() => {
store.dispatch('addMarker', L.latLng(47.412, -1.24));
}, 1400);
html,
body,
#app {
height: 100%;
margin: 0;
}
<script src="//unpkg.com/vue@latest/dist/vue.js"></script>
<script src="//unpkg.com/leaflet@1.0.3/dist/leaflet.js"></script>
<script src="//unpkg.com/vue2-leaflet@0.0.57/dist/vue2-leaflet.js"></script>
<script src="//unpkg.com/vuex@latest/dist/vuex.js"></script>
<link href="//unpkg.com/leaflet@1.0.3/dist/leaflet.css" rel="stylesheet" />
<div id="app">
<v-map :zoom="zoom" :center="center">
<v-tilelayer :url="url" :attribution="attribution"></v-tilelayer>
<v-marker v-for="marker in markers" :lat-lng="marker"></v-marker>
</v-map>
</div>
答案 1 :(得分:1)
考虑这种情况的事件总线;你有可以在地图上添加标记的组件,比如一个地址列表,当你点击一个时,一个引脚就会掉到它的位置。
// bus.js
import Vue from 'vue';
export const EventBus = new Vue();
// address-list.js
import { EventBus } from './bus.js';
methods: {
onClick () {
EventBus.$emit('add-marker', {x:123,y:345});
}
}
// map.js
import { EventBus } from './bus.js';
EventBus.$on('add-marker', coords => {
this.addMarker(coords).then(() => this.redrawMap())
});
直截了当,而不是很多代码。作为一个全球总线,显然你可以在任何必要的组件中重复使用。