我有一个vue.js组件,该组件包含一个查询Google Places API的搜索字段(为简单起见,已移除)。响应是带有地点的列表复选框。当用户检查某个地点时,我想在所选对象上设置一个标记checked
到true
。
但是,我也希望使这个属性具有反应性,但在运行时添加反应属性不起作用(参见https://vuejs.org/guide/reactivity.html)。
<template>
<form>
<input type="text" ref="complete" v-bind:placeholder="placeholder">
<fieldset v-if="places" class="checklist">
<h4>Select your store locations:</h4>
<div v-for="place in places">
<input :id="place.id" type="checkbox" v-model="place.checked">
<label :for="place.id">
{{ place.name }}<br>
<span class="subtext">{{ place.formatted_address }}</span>
</label>
</div>
</fieldset>
</form>
</template>
<script>
export default {
data() {
return {
places: [],
api: {
domain: 'https://maps.googleapis.com/maps/api/js',
key: 'API Key',
libraries: 'places',
},
};
},
mounted() {
window.onload = this.loadScript(
`${this.api.domain}?key=${this.api.key}&libraries=${this.api.libraries}`,
this.bindAutocomplete
);
},
watch: {
},
methods: {
loadScript(src, callback) {
const script = document.createElement('script');
document.body.appendChild(script);
if (callback) {
script.onload = callback;
}
script.src = src;
},
bindAutocomplete() {
this.autocomplete = new google.maps.places.SearchBox(
this.$refs.complete
);
this.autocomplete.addListener('places_changed', this.pipeAddress);
},
pipeAddress() {
this.places = this.autocomplete.getPlaces();
},
},
};
</script>
此组件有效,但我无法以编程方式将任何复选框设置为&#34;已选中&#34;,例如通过this.places.forEach((place) => { place.checked = true; }
。什么是实现这一目标的正确方法?
谢谢,
的Henning
答案 0 :(得分:1)
您需要在观察数据之前声明checked
属性,即在将其添加到data
之前。
执行此操作的一种方法是,在分配places
中的密钥之前,转换getPlaces()
返回的数组中的checked
对象以包含data
属性。< / p>
pipeAddress() {
this.places = this.autocomplete.getPlaces().map(
place => { place.checked = false; return place }
);
},
现在,当观察到数据时,checked属性将存在并因此被动,因此DOM可以相应地更新。
来自Vue博客的当您添加在观察数据时不存在的新属性时。由于ES5的限制并且为了确保跨浏览器的一致行为,Vue.js无法检测属性添加/删除。最佳实践是始终声明需要在前期进行反应的属性。如果您绝对需要在运行时添加或删除属性,请使用全局Vue.set或Vue.delete方法。