vue.js:根据 API 响应动态添加反应式复选框列表

vue.js: Dynamically add a reactive list of checkboxes based on API response

我有一个 vue.js 组件,它包含一个查询 Google 地点 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>

此组件有效,但我无法以编程方式将任何复选框设置为 "checked",例如通过 this.places.forEach((place) => { place.checked = true; }。实现这一目标的正确方法是什么?

谢谢,

亨宁

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

之前

一种方法是在分配给 getPlaces() 返回的数组中的 places 对象以包含 checked 属性 =12=].

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

现在,当观察到数据时,检查的 属性 将存在并因此具有反应性,因此 DOM 可以相应地更新。

Here's a fiddle

Explanation 来自 Vue 博客:

When you are adding a new property that wasn’t present when the data was observed. Due to the limitation of ES5 and to ensure consistent behavior across browsers, Vue.js cannot detect property addition/deletions. The best practice is to always declare properties that need to be reactive upfront. In cases where you absolutely need to add or delete properties at runtime, use the global Vue.set or Vue.delete methods.