Как получить доступ к методам внутри объекта в vuejs? - PullRequest
0 голосов
/ 30 апреля 2018

Я пытаюсь войти в систему с помощью Google vue, следуя документу Google, и все работает, но у меня нет доступа к методу внутри attachClickHandler.

new Vue({
    el: '#loginModal',
    data: { ...
    },
    methods: {
        gInit: function() {
            gapi.load('auth2', function() {
                auth2 = gapi.auth2.init({
                    client_id: 'MY-Client-id.apps.googleusercontent.com',
                    cookiepolicy: 'single_host_origin',
                    //scope: 'additional_scope'
                });
                auth2.attachClickHandler(document.getElementById('googleBtn'), {},
                    function(googleUser) {
                        const profile = googleUser.getBasicProfile();
                        const gplusObj = {
                            name: profile.getName(),
                            email: profile.getEmail(),
                            provider: 'google',
                            image: profile.getImageUrl(),
                            provider_user_id: profile.getId()
                        };

                        this.socialLogin(gplusObj);
                    },
                    function(error) {
                        alert(JSON.stringify(error, undefined, 2));
                    });
            });
        },
        socialLogin: function(data) {
            axios.post(`${this.api}/api/sociallogin`, data)
                .then(res => {
                    console.log(res);
                }).catch(err => {
                    console.log(err);
                });
        },
    },
    mounted: function() {
        this.gInit();
    }

})

Здесь вызов функции socialLogin() внутри attachClickHandler() дает ошибку this.socialLogin is not a function не определено. Почему это не работает?

Ответы [ 2 ]

0 голосов
/ 30 апреля 2018

Это потому, что вызов this.socialLogin находится в функции обратного вызова. Эта функция создает новый контекст, поэтому this изменяется и больше не будет вашим компонентом. Используйте функции стрелок. Они не изменятся this.

Редактировать: изменить код следующим образом:

gInit() {
    gapi.load('auth2', () => {
        ...
        auth2.attachClickHandler(document.getElementById('googleBtn'), {}, (googleUser) => {
            ...
            this.socialLogin(gplusObj);
        }, (error) => {
            alert(JSON.stringify(error, undefined, 2));
        });
    });
},

Подробнее по этой теме: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions, см. «Не отделяйте это».

0 голосов
/ 30 апреля 2018

Поскольку вы не сохранили this, попробуйте:

new Vue({
  el: '#loginModal',
  data: { ...
  },
  methods: {
    gInit: function() {
      let self = this // new added
      gapi.load('auth2', function() {
        auth2 = gapi.auth2.init({
          client_id: 'MY-Client-id.apps.googleusercontent.com',
          cookiepolicy: 'single_host_origin',
          //scope: 'additional_scope'
        });
        auth2.attachClickHandler(document.getElementById('googleBtn'), {},
          function(googleUser) {
            const profile = googleUser.getBasicProfile();
            const gplusObj = {
              name: profile.getName(),
              email: profile.getEmail(),
              provider: 'google',
              image: profile.getImageUrl(),
              provider_user_id: profile.getId()
            };
            console.log(e);
            self.socialLogin(gplusObj); //updated
          },
          function(error) {
            alert(JSON.stringify(error, undefined, 2));
          });
      });
    },
    socialLogin: function(data) {
      axios.post(`${this.api}/api/sociallogin`, data)
        .then(res => {
          console.log(res);
        }).catch(err => {
          console.log(err);
        });
    },
  },
  mounted: function() {
    this.gInit();
  }

})

this не будет передан автоматически, и вы должны уже знать это до изучения vue.

Кроме того, вы можете использовать arrow function, чтобы избежать изменения this:

new Vue({
  el: '#loginModal',
  data: { ...
  },
  methods: {
    gInit: function() {
      gapi.load('auth2', function() {
        auth2 = gapi.auth2.init({
          client_id: 'MY-Client-id.apps.googleusercontent.com',
          cookiepolicy: 'single_host_origin',
          //scope: 'additional_scope'
        });
        auth2.attachClickHandler(document.getElementById('googleBtn'), {},
          (googleUser) => { //updated
            const profile = googleUser.getBasicProfile();
            const gplusObj = {
              name: profile.getName(),
              email: profile.getEmail(),
              provider: 'google',
              image: profile.getImageUrl(),
              provider_user_id: profile.getId()
            };
            console.log(e);
            this.socialLogin(gplusObj);
          },
          function(error) {
            alert(JSON.stringify(error, undefined, 2));
          });
      });
    },
    socialLogin: function(data) {
      axios.post(`${this.api}/api/sociallogin`, data)
        .then(res => {
          console.log(res);
        }).catch(err => {
          console.log(err);
        });
    },
  },
  mounted: function() {
    this.gInit();
  }

})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...