gpt4 book ai didi

javascript - 从另一个组件切换 map 层可见性

转载 作者:搜寻专家 更新时间:2023-10-30 22:42:43 25 4
gpt4 key购买 nike

首先,我是一名设计专业的学生,​​我使用 Vue.js 为我的高级项目制作原型(prototype)。所以这不是真正的工作项目。只是一些日记应用程序的原型(prototype)。

我的问题是,我通过 Vue2Leaflet 构建了一个 map 组件有瓦片层。

在 Tile Layer 上,我渲染了一个 GeoJSON 文件,它有两个坐标对象。

我还有一个日期选择器组件,它通过 EventBus 发出值。

我的目标是:当日期选择器发出特定值时,关闭 <l-geo-json>并打开另一个 <l-geo-json> .

<l-geo-json>有一个参数是 :visible显示或隐藏。 :visible从 GeoJSON 对象获取参数。 datepicker发出一些用于更改 GeoJSON 参数的 bool 值。 GeoJSON 参数发生变化但未在 map 中呈现。

我认为,这是因为没有重新渲染 map 组件。

我的 map 组件是这样的:

<template>
<div v-if="refresh" id="MapView2">
<i class="material-icons geoLocate" v-on:click="geoLoc">location_searching</i>
<l-map :zoom="zoom" :options="{ zoomControl: false }" class="map" :center="center">
<l-tile-layer :url="url" :attribution="attribution"></l-tile-layer>
<l-geo-json :visible="yesterday.day" :geojson="bus.geojson" :options="bus.options"></l-geo-json>
<l-geo-json :visible="today.day" :geojson="today.geojson" :options="today.options"></l-geo-json>
</l-map>
</div>
</template>

<script>
import Vue from 'vue';
import Leaflet from 'leaflet';
import L from 'leaflet';
import { LMap, LTileLayer, LGeoJson } from 'vue2-leaflet';
import PopupContent from './GeoJson2Popup';
import { data, EventBus2 } from '../assets/geojson/sample-geojson.js';


export default {
name: 'MapView2',
components: {
LMap,
LTileLayer,
LGeoJson,
},
data(){
return {
zoom: 13,
center: {
lat: '',
lng: '',
},
url:'https://api.mapbox.com/styles/v1/mapbox/light-v9/tiles/256/{z}/{x}/{y}?access_token=...',
attribution: '',
yesterday: {
geojson: data.yesterday,
day: data.yesterday.visible,
options: {
onEachFeature: onEachFeature,
color: "#45B8FF",
fillOpacity: 0.8
}
},
today: {
geojson: data.today,
day: data.today.visible,
options: {
onEachFeature: onEachFeature,
color: "#45B8FF",
fillOpacity: 0.8
}
},
}
},
methods: {
geoLoc() {
navigator.geolocation.getCurrentPosition(position => {
this.position = position.coords;
this.center.lat = position.coords.latitude
this.center.lng = position.coords.longitude
this.zoom = 25
console.log(position.coords)
})
}
},
beforeCreate() {
if(navigator.geolocation){
navigator.geolocation.getCurrentPosition(position => {
this.isLoading = false
this.position = position.coords;
this.center.lat = position.coords.latitude
this.center.lng = position.coords.longitude
console.log(position.coords)
})
}
},
mounted() {
EventBus2.$on('mapDay', pickerValue => {
switch (pickerValue) {
case data.today.id:
data.yesterday.visible = true;
data.today.visible = false;
break;
case data.yesterday.id:
data.yesterday.visible = false;
data.today.visible = true;
break;
}
});
},
};
</script>

我的 geojson.js 文件也是这样

    import Vue from 'vue';
export const EventBus2 = new Vue();
export const data = {
today: {
"type": "FeatureCollection",
"id": "0520",
"visible": false,
"features": [ // geojson features and coordinates ]
},

yesterday: {
"type": "FeatureCollection",
"id": "0520",
"visible": false,
"features": [ // geojson features and coordinates ]
}
}

如您所见,日期选择器在 MMDD 中发出一些值格式。 Switch 语句通过 id 检查 GeoJSON 数据中的值.如果匹配,则更改 visible属性(property)。它实际上在日期选择器发出时发生了变化。

但它不会在 map 中呈现(GeoJSON 图层不会相应地改变可见性)。

我该怎么做?我应该使用 watch 吗?或类似的东西?如果是,我该如何使用它?

最佳答案

您应该直接更改您的实例data

为清楚起见,我将按照您从 geojson.js 文件导入为 data2 的方式进行操作。调用两者相同可能是您感到困惑的原因。

import { data as data2, EventBus2 } from '../assets/geojson/sample-geojson.js';

您的 GeoJSON 层可见性没有动态变化的原因是因为您使用来自 data2 的信息正确初始化了您的实例 dataday 属性>,但这不会将它们动态绑定(bind)到 data2 中的 future 修改。

因此,最简单的方法是在 "mapDay" 事件监听器中切换实例 dataday 属性,而不是信息在 data2 中。

EventBus2.$on('mapDay', pickerValue => {
switch (pickerValue) {
case data2.today.id:
this.yesterday.day = true;
this.today.day = false;
break;
case data2.dun.id:
this.yesterday.day = false;
this.today.day = true;
break;
}
});

您也可以同时切换datadata2,以防您希望data2 也同步,例如如果你在另一个组件中使用它。请注意,这样的策略会很脆弱,因为更改其他组件中的 data2 在这里不会有任何效果。

另一方面,您可以通过简单地将您的 pickerValue 存储在您的实例 data 中,并将其与您的 geojson.id 进行比较来简化可见性切换逻辑 :visible 属性绑定(bind)表达式::visible="pickerValue === yesterday.geojson.id"

代码示例:

Vue.component('map-view-2', {
template: '#map-view-2',
components: {
'l-map': Vue2Leaflet.LMap,
'l-tile-layer': Vue2Leaflet.LTileLayer,
'l-geo-json': Vue2Leaflet.LGeoJson,
},
data() {
return {
pickerValue: '0520',
url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
yesterday: {
geojson: data2.yesterday,
},
today: {
geojson: data2.today,
},
};
},
mounted() {
this.$root.$on('mapDay', pickerValue => {
this.pickerValue = pickerValue;
});
},
});

// Dummy DatePicker component for the sake of the demo.
Vue.component('date-picker', {
template: '#datepicker',
methods: {
handleInputChange(event) {
this.$root.$emit('mapDay', event.target.value);
},
},
});

const data2 = {
today: {
"type": "FeatureCollection",
"id": "0520",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [2.34, 48.86] // Left
},
}],
},
yesterday: {
"type": "FeatureCollection",
"id": "0519",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [2.35, 48.86] // Right
},
}],
},
};

new Vue({
el: '#app',
});
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet-src.js"></script>
<script src="https://unpkg.com/vue2-leaflet@1.0.2/dist/vue2-leaflet.js"></script>

<template id="map-view-2">
<div id="MapView2">
<l-map :zoom="11" style="height: 100px;" :center="[48.86, 2.35]">
<l-tile-layer :url="url" :attribution="attribution"></l-tile-layer>
<l-geo-json :visible="pickerValue === yesterday.geojson.id" :geojson="yesterday.geojson"></l-geo-json>
<l-geo-json :visible="pickerValue === today.geojson.id" :geojson="today.geojson"></l-geo-json>
</l-map>
</div>
</template>

<template id="datepicker">
<fieldset @change="handleInputChange">
<legend>Choose a date</legend>
<input type="radio" name="date" value="0520" id="today" checked />
<label for="today">Today 0520</label>
<input type="radio" name="date" value="0519" id="yesterday" />
<label for="yesterday">Yesterday 0519</label>
<input type="radio" name="date" value="none" id="none" />
<label for="none">None</label>
</fieldset>
</template>

<div id="app">
<map-view-2></map-view-2>
<date-picker></date-picker>
</div>

一种更加模块化的方法会将 pickerValue 数据公开为 prop,这样您就可以直接在父级(例如 App)级别修改它,而不必监听到您的 "mapDay" 事件:

Vue.component('map-view-2', {
template: '#map-view-2',
components: {
'l-map': Vue2Leaflet.LMap,
'l-tile-layer': Vue2Leaflet.LTileLayer,
'l-geo-json': Vue2Leaflet.LGeoJson,
},
props: {
// Receive the value directly from parent component / App.
pickerValue: {
type: String,
default: '0520',
},
},
data() {
return {
url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
yesterday: {
geojson: data2.yesterday,
},
today: {
geojson: data2.today,
},
};
},
});

// Dummy DatePicker component for the sake of the demo.
Vue.component('date-picker', {
template: '#datepicker',
props: {
value: {
type: String,
default: '0520',
},
},
methods: {
handleInputChange(event) {
// https://vuejs.org/v2/guide/components-custom-events.html#Customizing-Component-v-model
this.$emit('input', event.target.value);
},
},
});

const data2 = {
today: {
"type": "FeatureCollection",
"id": "0520",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [2.34, 48.86] // Left
},
}],
},
yesterday: {
"type": "FeatureCollection",
"id": "0519",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [2.35, 48.86] // Right
},
}],
},
};

new Vue({
el: '#app',
data() {
return {
pickerValue: '0519', // This value rules child components default value.
};
},
});
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet-src.js"></script>
<script src="https://unpkg.com/vue2-leaflet@1.0.2/dist/vue2-leaflet.js"></script>

<template id="map-view-2">
<div id="MapView2">
<l-map :zoom="11" style="height: 100px;" :center="[48.86, 2.35]">
<l-tile-layer :url="url" :attribution="attribution"></l-tile-layer>
<l-geo-json :visible="pickerValue === yesterday.geojson.id" :geojson="yesterday.geojson"></l-geo-json>
<l-geo-json :visible="pickerValue === today.geojson.id" :geojson="today.geojson"></l-geo-json>
</l-map>
</div>
</template>

<template id="datepicker">
<fieldset @change="handleInputChange">
<legend>Choose a date</legend>
<input type="radio" name="date" value="0520" id="today" :checked="value === '0520'" />
<label for="today">Today 0520</label>
<input type="radio" name="date" value="0519" id="yesterday" :checked="value === '0519'" />
<label for="yesterday">Yesterday 0519</label>
<input type="radio" name="date" value="none" id="none" :checked="value === 'none'" />
<label for="none">None</label>
</fieldset>
</template>

<div id="app">
<map-view-2 :picker-value="pickerValue"></map-view-2>
<date-picker v-model="pickerValue"></date-picker>
</div>

综上所述,如果您的工作只是为了设计原型(prototype),甚至不炫耀您的编程技能,那么即使 Vue 虽然已经非常简单,但对于您的任务来说可能有点过分了。

关于javascript - 从另一个组件切换 map 层可见性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50457497/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com