Vue - вызов метода из другого компонента (использует vue-маршруты) - PullRequest
0 голосов
/ 05 ноября 2019

Вот моя база App.vue, которая содержит router-view:

<template>
<div>
    <Navbar/>

    <div class="container-fluid">
        <router-view></router-view>
    </div>
</div>
</template>

<script>
import Navbar from './components/Navbar.vue';

export default {
    name: 'App',
    components: {
        Navbar
    }
}
</script>

В Navbar.vue у меня есть метод:

methods: {
    getLoggedStatus(){
        console.log('asdasd')
    }
}

Наконец, у меня естьLogin.vue, загруженный туда на router-view. Я хочу добраться до getLoggedStatus() от Navbar.vue в Login.vue. Как я могу добиться этого?

Я попытался установить ссылку на тег Navbar в App.vue:

<Navbar ref="navvy"/>

И вызвать Login.vue с помощью:

this.$refs.navvy.getLoggedStatus()

Но это не работает.

Ответы [ 2 ]

3 голосов
/ 05 ноября 2019

Ссылка работает только на детей. Вы визуализируете <Navbar> в приложении, поэтому вы не можете вызвать этот реф из логина. Вы можете получить доступ только к this.$refs.navvy из App.vue.

. Существует несколько вариантов решения вашей проблемы.

  1. Отправка события из входа в приложение, поэтому приложение вызываетметод из ссылки.

Вы можете установить прослушиватель в просмотре маршрутизатора следующим образом:

<router-view  @loggedStatus="callLoggedStatus"  />

При входе в систему, когда вы хотите вызватьnavbar getLoggedStatus, вместо этого вы бы отправили это событие:

this.$emit('loggedStatus')

А затем в App.vue вы определили бы callLoggedStatus методы, которые вызывают ref:

callLoggedStatus() {
  this.$refs.navvy.getLoggedStatus();
}

Учитывая, что вы добавляете ссылку на компонент <Navbar> в шаблоне APP.

Возможно, это решение наиболее похоже на предложенный вами код, но я думаю, что это беспорядок, и вам следует его избегать, поскольку выможет в конечном итоге прослушивать множество различных событий в вашем App.vue.

Использовать Vuex

Я точно не знаю, что делает getLoggedStatus, но если вы хотите изменить поведение своей панели навигации при входе пользователя, выВероятно, следует настроить хранилище vuex, поэтому вы регистрируетесь там, вошел пользователь в систему или нет. Затем в вашем компоненте navbar вы визуализируете вещи условно в зависимости от того, зарегистрирован пользователь или нет.

@ Ответ Ланы следует этой идее и, вероятно, является наиболее близким к официальному пути к худым в Vue.

Использование источника событий

Если вы хотите напрямую связываться между компонентами, не входящими в одну семью, я думаю, что источник событий является разумным выбором. После создания приложения вы можете настроить генератор событий всего приложения:

const app = new Vue({...});
window.emitter = new Vue();

(в этом примере мы используем новое Vue в качестве источника событий. Существует также модуль 'events', который позволяет использовать EventEmitter)

И тогда любой компонент может использовать его для отправки сообщений, поэтому вход в систему может сделать:

window.emitter.$emit('user-logged', myCustomPayload);

А Navbar, с другой стороны, может сделать:

window.emitter.$on('user-logged', function() {
  this.getLoggedStatus();
})

Этопоследний вариант не очень хорошо рассматривается в сообществе Vue - предпочтительным является Vuex, но я думаю, что для небольших приложений он самый простой.

Грязный хак

Вы всегда можете экспортировать свой компонент в окно. В хуке Navbar created вы можете сделать:

created() {
  window.Navbar = this;
}

А затем в Login.vue вы можете в любое время:

window.Navbar.getLoggedStatus()

И это будет работать. Тем не менее, это, безусловно, анти-паттерн и может нанести большой вред обслуживаемости вашего проекта, если вы начнете делать это с несколькими компонентами.

2 голосов
/ 05 ноября 2019

Похоже, getLoggedStatus возвращает глобальное состояние приложения. Используйте Vuex для управления этими глобальными переменными.

Создайте хранилище следующим образом:

// Make sure to call Vue.use(Vuex) first if using a module system
const store = new Vuex.Store({
  state: {
    loggedStatus: 0
  },
  getters: {
    getLoggedStatus: state => {
      // to compute derived state based on store state
      return state.loggedStatus 
    }
  }
})

Используйте store.state.loggedStatus в любом компоненте Vue для доступа к глобальному состоянию илииспользуйте методы получения, такие как store.getters.getLoggedStatus, если вам нужно вычислить производное состояние на основе состояния хранилища.

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