首先,我是设计学生,我使用Vue.js为我的高级项目进行原型设计。所以这不是真正的工作项目。只是一些日记应用程序的原型。
我的问题是,我通过Vue2Leaflet构建了一个包含Tile Layer的地图组件。
在Tile Layer上,我渲染了一个GeoJSON文件,该文件有两个坐标对象。
我还有一个datepicker组件,它通过EventBus发出值。
我的目标是:当datepicker发出特定值时,关闭<l-geo-json>
并启用另一个<l-geo-json>
。
<l-geo-json>
有一个显示或隐藏:visible
的参数。 :visible
从GeoJSON对象获取参数。 datepicker
会发出一些布尔值来更改GeoJSON参数。 GeoJSON参数更改但不在地图中呈现。
我认为,这是因为没有重新渲染地图组件。
我的地图组件如:
<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 ]
}
}
如您所见,datepicker以MMDD
格式发出一些值。 Switch语句按id
检查GeoJSON数据中的值。如果匹配,请更改visible
属性。当datepicker发出时,它实际上已经改变了。
但它不是在地图中渲染(GeoJSON图层不会相应地改变可见性)。
我该怎么做?我应该使用watch
或类似的东西吗?如果是,我该如何使用它?
答案 0 :(得分:2)
您只需直接更改实例data
。
为清楚起见,我会像您从geojson.js
文件中导入data2
一样。同时调用两者可能是您感到困惑的原因。
import { data as data2, EventBus2 } from '../assets/geojson/sample-geojson.js';
您的GeoJSON图层可见性未动态更改的原因是您使用data
中的信息正确初始化了实例day
和data2
属性,但这并未动态绑定它们未来data2
的修改。
因此,最简单的方法是切换data
事件监听器中的实例day
和"mapDay"
属性,而不是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;
}
});
您还可以切换data
和data2
,以防data2
也同步,例如如果你在另一个组件中使用它。请注意,这样的策略会很脆弱,因为更改其他组件中的data2
将不起作用。
另一方面,您只需将pickerValue
存储在实例data
中,然后将其与geojson.id
:visible
内的: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: '© <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
数据公开为"mapDay"
,以便您直接在父级(例如App)级别修改它,而不必听取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: '© <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.
};
},
});
event:
<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>
import datetime
commands = {}
while True:
cmd = input("Enter command: ").lower()
if "quit" == cmd:
break
now = datetime.datetime.now()
# Command already used at least once?
if cmd in commands:
# Check if time has elapsed
diff = now - commands[cmd]
if diff.seconds < 10:
# Time has not elapsed - print warning and start loop over
print(f"Wait {int(10-diff.seconds)} more seconds before using that command")
continue
# If this line is reached, it's ok to use the command
print(f"Using command: {cmd}")
# Reset time for this command
commands[cmd] = now
所有这一切,如果你的工作只是为了设计原型,甚至没有炫耀你的编程技巧,那么即使是Vue,虽然已经非常简单,但可能对你的任务来说太过分了。