@alenov
Программист

Как в Vue из одного компонента обратиться к свойству другого?

Vue 2.x, Webpack, приложение построено на однофайловых компонентах. Не могу понять, как Webpack всё это собирает.

Задача такая. Хотелось сделать обёртку (функция load) над вызовами axios, для удобства. Хотел поместить её в какой-нибудь my_lib.js, чтобы можно было обращаться к ней из любого компонента, но не смог найти способ, как это сделать.

Потом решил добавить эту функцию как метод в основной файл App.vue. Когда пишу код для Selector.vue в IDE (PyCharm), то он находит связи и подсвечивает подсказку, т.е. видно, что якобы метод load из App.vue доступен в Selector.vue.

main.js
---------------
import Vue from 'vue'
import App from './App.vue'
import store from './store'
import vuetify from './plugins/vuetify'
import axios from 'axios'

Vue.config.productionTip = false
Vue.prototype.axios = axios

new Vue({
  store,
  vuetify,
  render: h => h(App)
}).$mount('#app')


App.vue
---------------
<template>
...
</template>

<script>
import Selector from '@/components/Selector.vue'

export default {
  name: 'App',
  components: {
    Selector
  },
  methods: {
    load (command, { result, callback, data, method }) {
      this.axios({
        'site.com'
      }).then(response => {
        if (result) {
          result.data = response.data
          result.status = response.status
        }
      }).catch(error => {
        if (error.response) {
          if (result) {
            result.data = error.response.data
            result.status = error.response.status
          }
        } else if (error.request) {
          if (result) {
            result.error = error.message
          }
        }
      }).then(() => {
        if (callback) callback()
      })
    }
  }
}
</script>


Selector.vue
--------------
<template>
  <div class="text-center">
    <v-menu offset-y>
      <template v-slot:activator="{ on }">
        <v-btn
          outlined
          x-small
          width="100%"
          v-on="on"
        >{{ $store.state.locale }}</v-btn>
      </template>
      <v-list>
        <v-list-item
          :value="$store.state.locale"
          v-for="(item,key) in messages"
          :key="key"
          @click="change_locale(key)"
        >
          <v-list-item-title>{{ item.title }}</v-list-item-title>
        </v-list-item>
      </v-list>
    </v-menu>
  </div>
</template>

<script>
import { messages } from '@/assets/lang.js'

export default {
  name: 'Selector',
  data: () => ({
    messages: messages
  }),
  methods: {
    change_locale (key) {
      const result = {}
      this.load(
        '/set_lang',
        {
          result,
          data: { lang: key },
          callback: () => {
            if (result.success) {
              this.$store.dispatch('setLocale', key)
            }
          }
        }
      )
    }
  }
}
</script>


Но когда исполняю, браузер выдаёт:

[Vue warn]: Error in v-on handler: "TypeError: this.load is not a function"


Как из одного компонента сослаться на свойство или метод другого? Если всё написать в одном файле (раньше так и делал), то можно было сделать

var vm = new Vue(...)

и потом везде иметь доступ через vm. А тут просто написано:

new Vue({
  store,
  vuetify,
  render: h => h(App)
}).$mount('#app')


Я не понимаю, как это работает...

И как вообще корректно сделать эту обёртку, чтобы можно было пользовать её в любом месте приложения? Была мысль использовать storage: поместить load в хранилище и вызывать его как this.$store.load(). Будет ли это по феншую или это костыль?
  • Вопрос задан
  • 384 просмотра
Решения вопроса 1
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы