vue.js:根据API响应动态添加一个被动复选框列表

时间:2016-10-19 05:45:54

标签: javascript vue.js vue-component

我有一个vue.js组件,该组件包含一个查询Google Places API的搜索字段(为简单起见,已移除)。响应是带有地点的列表复选框。当用户检查某个地点时,我想在所选对象上设置一个标记checkedtrue

但是,我也希望使这个属性具有反应性,但在运行时添加反应属性不起作用(参见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

1 个答案:

答案 0 :(得分:1)

您需要在观察数据之前声明checked属性,即在将其添加到data之前。

执行此操作的一种方法是,在分配places中的密钥之前,转换getPlaces()返回的数组中的checked对象以包含data属性。< / p>

pipeAddress() {
    this.places = this.autocomplete.getPlaces().map(
        place => { place.checked = false; return place }
    );
},

现在,当观察到数据时,checked属性将存在并因此被动,因此DOM可以相应地更新。

Here's a fiddle

来自Vue博客的

Explanation

  

当您添加在观察数据时不存在的新属性时。由于ES5的限制并且为了确保跨浏览器的一致行为,Vue.js无法检测属性添加/删除。最佳实践是始终声明需要在前期进行反应的属性。如果您绝对需要在运行时添加或删除属性,请使用全局Vue.set或Vue.delete方法。