在Vue / Laravel中使用Google Map

时间:2019-02-01 12:44:20

标签: javascript vue.js vuejs2

尝试将Google Map实现为Vue组件。但是很难。实际上,没有错误。但也没有地图:)好的,我到目前为止在下面尝试的内容。

在laravel刀片中,我设置了我的api。

<script async defer src="https://maps.googleapis.com/maps/api/js?key={{env('GOOGLE_MAPS_API')}}&callback=initMap"></script>

然后在Vue组件中;

data() {
        return {
            mapName: "map",
            //some other codes
        }           
},

mounted() {
        this.fetchEstates();
},
methods: {
        fetchEstates(page = 1) {
            axios.get('/ajax', {
                params: {
                    page
                }}).then((response) => {
                    // console.log(response);
                    this.estates = response.data.data;
                    //some other codes....
                    //some other codes....


},
computed: {

        //some other functions in computed... 
        //

        initMap: function(){
                    var options =
                        {
                            zoom : 6,
                            center : {
                                lat:34.652500,
                                lng:135.506302
                            }
                        };

                    var map = new google.maps.Map(document.getElementById(this.mapName), options);
                    var marker = new google.maps.Marker({
                        map: map,
                        icon: 'imgs/marker.png',
                        url: "/pages/estates.id",
                        label: {
                            text: this.estates.price,
                            color: "#fff",
                        },
                        position: {
                            lat: this.estates.lat,
                            lng: this.estates.lng
                        }
                    });
                        google.maps.event.addListener(marker, 'click', function () {
                            window.location.href = this.url;
                    });


                }
<div id="map"></div>

最后一个标记url id绑定在这样的控制器中,

public function details($id)
{
    $estates = allestates::where('id', $id)->first();

    return view('pages.details', compact('estates'));

}

我在Vue js中缺少什么吗?谢谢!

2 个答案:

答案 0 :(得分:1)

根据我们在评论中的讨论,我意识到您的问题是因为在执行this.estates时仍未定义initMap()。请记住,您正在使用异步操作(通过axios)填充this.estates,因此在运行时未定义。您可以做的是:

  1. 保留initMap()中的地图初始化逻辑
  2. 移动所有Google Map标记的创建,直到axios promise被解决。您可以将所有内容抽象为另一种方法,例如insertMarkers()

另外,请记住,您需要在应用程序/组件数据中定义estates,否则它将不会起作用。

这里是一个例子:

data() {
    return {
        mapName: "map",

        // Create the estate object first, otherwise it will not be reactive
        estates: {}
    }           
},

mounted() {
    this.fetchEstates();
    this.initMap();
},
methods: {
    fetchEstates: function(page = 1) {
        axios.get('/ajax', {
            params: {
                page
            }}).then((response) => {
                this.estates = response.data.data;

                // Once estates have been populated, we can insert markers
                this.insertMarkers();

                //pagination and stuff... 
            });
    },

    // Iniitialize map without creating markers
    initMap: function(){
        var mapOptions =
            {
                zoom : 6,
                center : {
                    lat:34.652500,
                    lng:135.506302
                }
            };

        var map = new google.maps.Map(document.getElementById(this.mapName), mapOptions);
    },

    // Helper method to insert markers
    insertMarkers: function() {
        var marker = new google.maps.Marker({
            map: map,
            icon: 'imgs/marker.png',
            url: "/pages/estates.id",
            label: {
                text: this.estates.price,
                color: "#fff",
            },
            position: {
                lat: this.estates.lat,
                lng: this.estates.lng
            }
        });

        google.maps.event.addListener(marker, 'click', function () {
            window.location.href = this.url;
        });
    }
},

更新:事实证明,您尚未解决this.estates的数据结构问题。看来您是从端点而不是对象接收数组,因此this.estates将返回一个数组,当然this.estates.lat将是未定义的。

如果要遍历整个数组,则必须在添加标记的同时使用this.estates.forEach()遍历每个遗产,即:

data() {
    return {
        mapName: "map",

        // Create the estate object first, otherwise it will not be reactive
        estates: {}
    }           
},

mounted() {
    this.fetchEstates();
    this.initMap();
},
methods: {
    fetchEstates: function(page = 1) {
        axios.get('/ajax', {
            params: {
                page
            }}).then((response) => {
                this.estates = response.data.data;

                // Once estates have been populated, we can insert markers
                this.insertMarkers();

                //pagination and stuff... 
            });
    },

    // Iniitialize map without creating markers
    initMap: function(){
        var mapOptions =
            {
                zoom : 6,
                center : {
                    lat:34.652500,
                    lng:135.506302
                }
            };

        var map = new google.maps.Map(document.getElementById(this.mapName), mapOptions);
    },

    // Helper method to insert markers
    insertMarkers: function() {

        // Iterate through each individual estate
        // Each estate will create a new marker
        this.estates.forEach(estate => {
            var marker = new google.maps.Marker({
                map: map,
                icon: 'imgs/marker.png',
                url: "/pages/estates.id",
                label: {
                    text: estate.price,
                    color: "#fff",
                },
                position: {
                    lat: estate.lat,
                    lng: estate.lng
                }
            });

            google.maps.event.addListener(marker, 'click', function () {
                window.location.href = this.url;
            });
        });
    }
},

答案 1 :(得分:0)

从您发布的屏幕快照中可以看到,this.estates是一个对象数组?如果是这种情况,则需要使用forEach

遍历数组
this.estates.forEach((estate, index) => { 
    console.log(estate.lat); 
    //handle each estate object here
});

或者如果只对第一项感兴趣,可以像this.estates[0].lat这样使用数组中的第一项。