VueJS: Лучшая практика для работы с глобальным объектом между компонентами? - PullRequest
0 голосов
/ 15 февраля 2019

существует User.js класс и объект пользователя (user = new User();).

Объект user используется во всех вложенных компонентах.в классе User есть так много важных методов.

Как я могу просто использовать / access this.user или this.$user и его методы в любом компоненте?

1-решение (временное рабочее решение): установите user в хранилище vuex и определите во всех компонентах 'data:

data(){
  return {
    user:this.$store.state.user
  }
}

Минусы:в каждом компоненте это должно быть добавлено.Примечание: компонентов так много.

2-решение : добавление пользователя в прототип Vue , подобный плагину:

Vue.prototype.$user = user

Минусы: когда данные user изменяются, они не влияют на элемент DOM (UI).

3-решение : добавление компонентов реквизита .

Минусы: в каждом компоненте это должно быть добавлено.Примечание. Опять же, существует так много компонентов.

Все найденные мной решения имеют проблемы, особенно когда проект становится все больше и больше.

Любое предложение и решение будет оценено!

Ответы [ 6 ]

0 голосов
/ 15 февраля 2019

На основе ответа @Denis, в частности Предложение 3 , Вот UserPlugin.js:

import store from '@/store/store';
import User from './User';

const UserPlugin = {
  install(Vue) {
    const $user = new User();
    window.$user = $user;
    store.commit('setUser', $user);
    Vue.mixin({
      computed: {
        $user() {
          return store.state.user;
        }
      }
    });
  }
};
export default UserPlugin;

и main.js:

import UserPlugin from './common/UserPlugin';

Vue.use(UserPlugin);

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

ДляДля дальнейшего использования я опубликовал небольшую библиотеку для решения таких проблем:

https://www.npmjs.com/package/vue-global-var

0 голосов
/ 15 февраля 2019

Я только что создал минимальные коды и поле , чтобы прояснить идею о том, как dependency Injection работает в vue.

0 голосов
/ 15 февраля 2019

Примечание: относится к Vue 2x

Предложение 1: Использование геттеров из vuex

  • Вы можете использовать getters вместе с mapGetters из Vuex, чтобы включить пользователей в вычисляемые свойствадля каждого компонента.

Vuex

getters: {
  // ...
  getUser: (state, getters) => {
    return getters.user
  }
}

компонент

import { mapGetters } from 'vuex'
computed: {
  ...mapGetters([getUser])
}

Предложение 2: добавить наблюдателя через плагин

Vue

// When using CommonJS via Browserify or Webpack
const Vue = require('vue')
const UserPlug = require('./user-watcher-plugin')

// Don't forget to call this
Vue.use(UserPlug)

user-watcher-plugin.js

const UserPlug = {
  install(Vue, options) {
    // We call Vue.mixin() here to inject functionality into all components.

    Vue.watch: 'user'
  }
};

export default UserPlug;

Предложение 3: добавить вычисляемое свойство user в качестве плагина через mixin

Vue

// When using CommonJS via Browserify or Webpack
const Vue = require('vue')
const UserPlug = require('./user-watcher-plugin')

// Don't forget to call this
Vue.use(UserPlug)

user-watcher-plugin.js

const UserPlug = {
  install(Vue, options) {
    // We call Vue.mixin() here to inject functionality into all components.

    Vue.mixin({
      computed: {
        user: function() {
          return this.$store.state.user
        }
      }
    })
  }
};

export default UserPlug;
0 голосов
/ 15 февраля 2019

Предполагая, что вы на самом деле не используете все методы / атрибуты user в каждом компоненте, а подмножество их каждый раз, я не вижу никакой причины, по которой решения 1 и 2 не работают для вас, поскольку передачацелый user объект для каждого компонента не является необходимым.

Допустим, у вашего объекта User есть некоторые атрибуты (a1, a2, a3 и т. д.) и методы (m1, m2, m3 ...),Если компоненту нужны только некоторые из них (например, a1, a2, m1, m2, m3), тогда с Vuex вы можете использовать функции отображения (mapState, mapGetters, mapMutations и mapActions), чтобы получить точную информацию из user

import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'
export default {
    computed: {
        ...mapState('user', [ 'a1' ]),
        ...mapGetters('user', [ 'a2' ])
    },
    methods: {
        ...mapMutations('user', [ 'm1' ]),
        ...mapActions('user', [ 'm2', 'm3' ])
    }
}

В решении 2 (с использованием прототипа) для обновления компонента при изменении данных user вы можете сопоставить необходимые данные с компонентом через methods.

export default {
    methods: {
        userA1() {
            return this.$user.attributes.a1;
        },
        userM1() {
            this.$user.methods.m1();
        }
        // and so on
    }
}

Еще лучше,Вы можете создавать миксины для явного отображения данных из user и повторно использовать свои миксины, чтобы избежать дублирования кода в компонентах.Его можно применять как для решения Vuex, так и для решения-прототипа.

// mixin1:
const mixin1 = {
    computed: {
        ...mapState('user', [ 'a1' ]),
    },
    methods: {
        ...mapMutations('user', [ 'm1' ])
    }
}

// mixin2:
const mixin2 = {
    computed: {
        ...mapGetters('user', [ 'a2' ]),
    },
    methods: {
        ...mapActions('user', [ 'm2', 'm3' ])
    }
}

// component1
export default {
    mixins: [ mixin1 ]
}

// component 2
export default {
    mixins: [ mixin1, mixin2 ]
}

Но если вам действительно нужно передать весь объект user каждому компоненту, то ничего не поделаешь.Скорее, вы должны проверить свою реализацию и посмотреть, есть ли лучший способ разбить объект на более значимые.

0 голосов
/ 15 февраля 2019

Вы можете использовать mixins для добавления User.js к вашему корневому компоненту, например

import userLib from './User';
//User.js path should correct

Затем

var app = new Vue({
    router,
    mixins: [
        userLib
    ],
  //.....
});

После этого вы можете использовать любой из этих User методов в вашемлюбой компонент, например

this.$parent.userClassMehtod();

или доступ к данным

this.$parent.userClassData;

Наконец, не забудьте добавить export default{//..} в User.js

Примечание: это только работаесли вы экспортируете весь метод User.js в export default

0 голосов
/ 15 февраля 2019

Вы можете иметь второй экземпляр Vue и объявить реактивное свойство.

См .: Глубина реактивности

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