我以前用React方式处理这个问题,单向数据绑定和状态,所以我很难用Vue来思考它。
我有一张地图,根据新闻故事的lat / lng呈现点数。当用户更改选择的值时,地图上的点会更新。当用户点击某个点时,会打开一个弹出窗口,其中包含指向该故事的链接。但是,我不能让这两个功能一起工作。
这是我的Vue模板:
<div class="row">
<div id="map" class="map"></div>
</div>
<select v-model="selectedMonth">
<option disabled value="">Please select one</option>
<option>January 2018</option>
<option>December 2017</option>
<option>November 2017</option>
<option>October 2017</option>
</select>
<button v-on:click="reset">Reset all</button>
<div class="row">
<div class="col col-xs-12 col-sm-6 col-md-3 col-lg-3"
v-for="(story, index) in displayedStories">
<img v-bind:src="story.img_src" />
<br />
<a v-bind:href="story.url" target="_blank">{{ story.card_title }}</a>
<p>{{ story.published }}</p>
</div>
</div>
和JS:
export default {
name: 'app',
data() {
return {
leafleftMap: null,
tileLayer: null,
markers: [],
allStories: [],
selectedMonth: null,
}
},
mounted() {
this.getNodes()
this.initMap()
},
computed: {
displayedStories() {
const displayedStories = this.selectedMonth
? dateFilter(this.selectedMonth, this.allStories)
: this.allStories
if (this.leafleftMap) {
/* remove old markers layer */
this.leafleftMap.removeLayer(this.markers)
/* create a new batch of markers */
const markers = displayedStories.map(story => L.marker(story.coords)
.bindPopup(mapLink(story))
)
const storyMarkers = L.layerGroup(markers)
/* add current markers to app state and add to map */
this.markers = storyMarkers
this.leafleftMap.addLayer(storyMarkers)
this.changedMonth = this.selectedMonth
}
return displayedStories
},
},
methods: {
getNodes() { /* make api request */ }
initMap () { /* initialize map with */ }
},
}
问题在于行this.leafleftMap.removeLayer(this.markers)
。当它出现时,标记会使用选择按钮进行渲染和更改,但弹出窗口不起作用。当我删除该行时,弹出窗口可以正常工作,但是当选择更改时,地图将无法更新。
我尝试在select:
中添加自定义指令<select v-model="selectedMonth" v-updateMonth>
希望在JavaScript制定时关注:
directives: {
updateMonth: {
update: function(el, binding, vnode) {
console.log('select updated')
vnode.context.leafleftMap.removeLayer(vnode.context.markers)
}
}
},
但是只要页面上的任何内容发生变化,就会调用该指令,而不仅仅是在我更新select时。
我只是在更改选择时尝试调用函数(删除标记),但似乎无法在Vue中使用它。它想要在每次更新时调用每个函数。
答案 0 :(得分:0)
我能够用@change
来解决这个问题,我想我更了解何时在Vue中使用computed。
首先,我将大量更新逻辑移出计算:
computed: {
displayedStories() {
return this.selectedMonth
? dateFilter(this.selectedMonth, this.allStories)
: this.allStories
},
},
所以它只是返回一个数组。然后我在select:
中添加了一个监听器<select v-model="selectedMonth" @change="updateStories()">
然后创建了一个处理该更改的新方法:
methods {
updateStories() {
const markers = displayedStories.map(story => L.marker(story.coords)
.bindPopup(mapLink(story)))
const storyMarkers = L.layerGroup(markers)
this.markers = storyMarkers
this.leafleftMap.addLayer(storyMarkers)
this.changedMonth = this.selectedMonth
},
},