Vuex plugin test

by Sergei Sokolov

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.6.2/vuex.min.js"></script>
<div id="app">
  <h2>Vue app counter: {{ counter }}</h2>
</div>


<div id="habr"></div>

CSS

body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

#habr {
  color: white;
  margin: 10px 0;
}

Vue

/**
 * для вопроса https://qna.habr.com/q/1080632
 * Можно ли реактивно получать изменения Vuex во внешнем js файле?
 */
Vue.use(Vuex);

// Какой-то класс
class Habr {
  _classCounter = 0;
  
  set classCounter(value) {
    this._classCounter = value;
    document.getElementById("habr")
      .innerText = "Non-Vue class updated its prop to " + this.classCounter;
  }
  
  get classCounter() {
    return this._classCounter;
  }
}

const habr = new Habr();

const myPluginMaker = (target, propName) => (store) => {
  store.subscribe((mutation, state) => {
    if (mutation.type === "increment") {
      target[propName] = state.count;
    }
  })
}

const myPlugin = myPluginMaker(habr, "classCounter");

// Store
const store = new Vuex.Store({
  plugins: [myPlugin],
  state: {
    count: 0
  },
  mutations: {
    increment (state) { state.count++ }
  },
  actions: {
    increment_action: (context) => {
      setTimeout(() => context.commit("increment"), 1000);
    }
  },
})

// Vue app
new Vue({
  store,
  el: "#app",
  computed: {
    counter: () => store.state.count,
  }
})

// Dispatch async action
store.dispatch("increment_action");