Vue - сделать вывод из глобальной функции реактивным - PullRequest
0 голосов
/ 19 октября 2019

Я начал использовать Vue некоторое время назад вместе с компонентами Vue-cli и Single File. У меня есть «проблема», я хочу иметь глобальную функцию, которая возвращает форматированный текст компонентам (используется в большинстве компонентов моего приложения) в зависимости от текущих (глобальных) настроек этой «функции» (или класса),Я хочу, чтобы при изменении настроек (в данном примере currentKey) все компоненты, использующие эту функцию, обновляли значение. Короче говоря: currentKey изменяется - текст перерисовывается, чтобы соответствовать новому возвращаемому значению глобальной функции test.

В этом есть некоторая дополнительная логика, но это самый простой пример, который я придумал.

В этом примере вы можете видеть, что есть 5-секундный интервал, который циклически перебирает переменную currentKey, поэтому изменяется выход функции test. Я бы хотел, чтобы компоненты обновлялись соответственно каждые 5 секунд. Я пытался использовать вычисленные значения и другие вещи, которые нашел, но не смог заставить его работать так, как я хочу.

Как заставить компоненты обновляться всякий раз, когда я изменяю переменную currentKey?

Vue.component('component1', {
  template: '<div>{{ $test("name") }}</div>',
});

Vue.component('component2', {
  template: '<div>{{ $test("name2") }}</div>',
});

var table = {
  keyone: {
    name: 'TEST NAME FROM FIRST KEY',
    name2: 'TEST NAME 2 FROM FIRST KEY',
  },
  keytwo: {
    name: 'TEST NAME FROM <b>SECOND</b> KEY',
    name2: 'TEST NAME 2 FROM <b>SECOND</b> KEY',
  }
};
var currentKey = 'keyone';

Vue.prototype.$test = function(name) {
  return table[currentKey][name];
};

setInterval(function() {
  if(currentKey == 'keyone')
    currentKey = 'keytwo';
  else currentKey = 'keyone';
  console.log('Key changed to', currentKey);
}, 5000);

new Vue({
    el: '#app',
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <component1></component1>
  <component2></component2>
</div>

1 Ответ

2 голосов
/ 19 октября 2019

Реактивность - это все о свойствах объектов. Когда объект является наблюдаемым, Vue может отслеживать чтение и запись его свойств.

Поэтому все, что вам нужно сделать, - это сделать currentKey свойством наблюдаемого объекта, и вся магия реактивности сработает.

Пока вы используете Vue 2.6, вы можете использовать Vue.observable напрямую для создания наблюдаемого объекта. В более ранних версиях вам нужно было создать фиктивный экземпляр Vue и использовать функцию data, чтобы вместо этого применить реактивность к объекту.

Vue.component('component1', {
  template: '<div>{{ $test("name") }}</div>',
});

Vue.component('component2', {
  template: '<div>{{ $test("name2") }}</div>',
});

var table = {
  keyone: {
    name: 'TEST NAME FROM FIRST KEY',
    name2: 'TEST NAME 2 FROM FIRST KEY',
  },
  keytwo: {
    name: 'TEST NAME FROM <b>SECOND</b> KEY',
    name2: 'TEST NAME 2 FROM <b>SECOND</b> KEY',
  }
};

var config = Vue.observable({
  currentKey: 'keyone'
});

Vue.prototype.$test = function(name) {
  return table[config.currentKey][name];
};

setInterval(function() {
  if(config.currentKey == 'keyone')
    config.currentKey = 'keytwo';
  else config.currentKey = 'keyone';
  console.log('Key changed to', config.currentKey);
}, 5000);

new Vue({
    el: '#app',
});
<script src="https://unpkg.com/vue@2.6.10/dist/vue.js"></script>
<div id="app">
  <component1></component1>
  <component2></component2>
</div>

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

https://vuejs.org/v2/api/#Vue-observable

...