首页 > 解决方案 > 在child中设置父组件的数据

问题描述

在父组件中,将变量作为道具发送给子组件(DirectionsRenderer)

在孩子中有功能(DirectionsRenderer.js 中的preparePoints 功能)设置这个;

但无法访问该函数内的“ this ”引用

家长:

<template>
  <div>
    <div>
      <h2>Start</h2>
      <label>
        <gmap-autocomplete @place_changed="setStartPlace"></gmap-autocomplete>
        <button @click="addStartMarker">Add</button>
      </label>
      <br />
    </div>
    <div>
      <h2>End</h2>
      <label>
        <gmap-autocomplete @place_changed="setEndPlace"></gmap-autocomplete>
        <button @click="addEndMarker">Add</button>
      </label>
      <br />
    </div>
    <br />
    <gmap-map ref="xyz" :center="center" :zoom="7" style="width:100%;  height: 400px;">
      <gmap-marker
        :key="index"
        v-for="(m, index) in markers"
        :position="m.position"
        @click="center=m.position"
      ></gmap-marker>
      <DirectionsRenderer
        :v-model="pointList" //this is what I want filled by child component
        travelMode="DRIVING"
        :origin="origin"
        :destination="destionation"
      />
      {{pointList}}
    </gmap-map>
  </div>
</template>

<script>
import DirectionsRenderer from "./DirectionsRenderer.js";

export default {
  components: {
    DirectionsRenderer,
  },
  name: "GoogleMap",
  data() {
    return {
    
      center: { lat: 41.85, lng: -87.65 },
      pointList: [],
      markers: [],
      places: [],
      path: [],
      currentPlace: null,
      startPoint: {},
      endPoint: {},
    };
  },
  computed: {
    origin() {
      if (!this.startPoint) return null;
      return this.startPoint;
    },
    destionation() {
      if (!this.endPoint) return null;
      return this.endPoint;
    },
  },
  mounted() {
    this.geolocate();
  },

  methods: {
    getPoints() {
      return this.pointList;
    },
    setStartPlace(place) {
      this.currentPlace = place;
    },
    setEndPlace(place) {
      this.currentPlace = place;
    },
    addStartMarker() {
      if (this.currentPlace) {
        const marker = {
          lat: this.currentPlace.geometry.location.lat(),
          lng: this.currentPlace.geometry.location.lng(),
        };
        this.startPoint = marker;
        this.markers[0] = { position: marker };
        this.places.push(this.currentPlace);
        this.center = marker;
        this.currentPlace = null;
      }
    },
    addEndMarker() {
      if (this.currentPlace) {
        const marker = {
          lat: this.currentPlace.geometry.location.lat(),
          lng: this.currentPlace.geometry.location.lng(),
        };
        this.endPoint = marker;
        this.markers[1] = { position: marker };
        this.places.push(this.currentPlace);
        this.center = marker;
        this.currentPlace = null;
      }
    },
    geolocate: function () {
      navigator.geolocation.getCurrentPosition((position) => {
        this.center = {
          lat: position.coords.latitude,
          lng: position.coords.longitude,
        };
      });
    },
  },
};
</script>

孩子(DirectionsRenderer.js):

export default MapElementFactory({
    name: "directionsRenderer",

    ctr() {
        return window.google.maps.DirectionsRenderer;
    },

    events: [],

    mappedProps: {},

    props: {
        pointList: { type: Array },
        origin: { type: Object },
        destination: { type: Object },
        travelMode: { type: String }
    },
    methods: {
        preparePoints: (array) => {

            var result = []
            array.forEach(element => {
                result.push({ lat: element.lat(), lng: element.lng() })
            });
            debugger;
            this.pointList = result;//**Throws exception cant read 'pointList' of undefined
        }
    },

    afterCreate(directionsRenderer) {
        let directionsService = new window.google.maps.DirectionsService();
        this.$watch(
            () => [this.origin, this.destination, this.travelMode],
            () => {
                let { origin, destination, travelMode } = this;
                if (!origin || !destination || !travelMode) return;

                var self = this;
                directionsService.route(
                    {
                        origin,
                        destination,
                        travelMode
                    },
                    (response, status) => {
                        self.preparePoints(response.routes[0].overview_path);
         
                    }
                );
            }
        );
    },
});

如何正确检索孩子的数据?孩子中有数组我需要做的就是在孩子中设置'pointList'并在父母中使用它。

标签: vuejs2

解决方案


您不能使用事件。

问题是,您没有子/父关系,而是更深层次的层次结构。你可以用provide/inject这个。

在你的父母中,使用

export default {
  ... all your old code ...
  provide() {
    return {
      // Notice that this is a lambda => this gets bound to the this in provide, which is the vue instance
      pointsCallback: (points) => this.pointList = points
    }
  }
}

在你的孩子中,使用这个:

export default {
  inject: ['pointsCallback'],

  // Your other code ...
  // { {
  // Somewhere after  self.preparePoints(response.routes[0].overview_path);
  this.pointsCallback(theNewPointsListYouComputed);
  // This will call the pointsCallback you defined in your parent.

  // } } and so on
}

推荐阅读