Home  >  Article  >  Web Front-end  >  Detailed explanation of how to implement vuex (detailed tutorial)

Detailed explanation of how to implement vuex (detailed tutorial)

亚连
亚连Original
2018-06-06 14:18:551830browse

This article mainly introduces how to implement a simple vuex. Now I will share it with you and give you a reference.

First we need to know why we use vuex. Communication between parent and child components can be done using props and custom events, and simple non-parent and child component communication uses bus (an empty Vue instance). Then use vuex to solve complex non-parent-child component communication.

It doesn’t matter if you just know how to use vuex. Everyone can read the documentation and type the code. Don’t you want to know how vuex is implemented? !

Putting aside the source code of vuex, let's first think about how to implement a simple "vuex". How simple is it? I don’t want getters, mutations, actions, etc., I just want state.

Non-parent-child component communication

Before implementation, we have to review the implementation of bus, borrowing the example from the official website:

var bus = new Vue()

// 触发组件 A 中的事件
bus.$emit('id-selected', 1)

// 在组件 B 创建的钩子中监听事件
bus.$on('id-selected', function (id) {
 // ...
})

Thinking back to those days, I didn't know where to put the instantiated bus, so I had no choice but to put it under window and keep using window.bus. Although this is fine, it still affects the global scope.

Suddenly one day, I found that I could mount it under the root instance of vue (say goodbye to window.bus from now on), so I got:

var app = new Vue({
 el: '#app',
 bus: bus
})

// 使用 bus
app.$options.bus

// or
this.$root.$options.bus

Then I discovered that bus is actually not Only on events can communicate. In fact, bus is a Vue instance, where data is responsive. For example, there are two non-parent-child components under the root instance of app, both of which use bus data, so they respond synchronously.

var bus = new Vue({
 data: {
  count: 0
 }
})

Above, subcomponent a modifies count. If subcomponent b uses count, then it can respond to the latest count value.

After saying so much, haven’t you discovered it yet? Isn’t this just about realizing communication between non-components, the state of vuex? !

Encapsulation bus

Yes, encapsulate the bus just now. This is the simplest "vuex" (only with the function of state). First, we will have a root instance app with two non-parent-child components childA and childB .

html The implementation of the code is as follows:

<p id="app">
 <child-a></child-a>
 <child-b></child-b>
</p>

Implementation of non-parent-child components

Then there are two non-parent-child components and the implementation of app, child component They all use the count of the bus, which is represented here by store.state, which is consistent with vuex:

// 待实现
const store = new Store(Vue, {
 state: {
  count: 0
 }
})

// 子组件 a
const childA = {
 template: &#39;<button @click="handleClick">click me</button>&#39;,
 methods: {
  handleClick () {
   this.$store.state.count += 1
  }
 }
}

// 子组件 b
const childB = {
 template: &#39;<p>count: {{ count }}</p>&#39;,
 computed: {
  count () {
   return this.$store.state.count
  }
 }
}

new Vue({
 el: &#39;#app&#39;,
 components: {
  &#39;child-a&#39;: childA,
  &#39;child-b&#39;: childB
 },
 store: store
})

See that there is a Store to be implemented in the code. The required parameters, because I am too lazy to use Vue.use() here, so I directly pass Vue as a parameter for use, and then the second parameter is consistent with the parameter we passed in using vuex.

Implementation of Store

The next step is the implementation of Store, a two-step implementation:

  1. Create a bus instance;

  2. Let all sub-components have access to this.$store.

The first step is already mentioned above. The second step mainly uses Vue.mixin to mix globally, but it just finds the root instance with the store and assigns the store on the Vue prototype. It also allows the root instance app to be mixed in without specifically writing mixins.

class Store {
 constructor (Vue, options) {
  var bus = new Vue({
   data: {
    state: options.state
   }
  })

  this.install(Vue, bus)
 }
 
 install (Vue, bus) {
  Vue.mixin({
   beforeCreate () {
    if (this.$options.store) {
     Vue.prototype.$store = bus
    }
   }
  })
 }
}

The implemented Store is a simple "vuex", which has the state of vuex, which is enough to allow simple communication between non-parent and child components.

Create a bus instance in the constructor of Store and inject it into the prototype of Vue, so that all components can access this.$store, which is the bus instance. this.$store is a Vue instance, so accessing this.$store.state.count actually accesses data, thereby achieving response synchronization between non-parent and child components. All source code is available here.

The above is what I compiled for everyone. I hope it will be helpful to everyone in the future.

Related articles:

What security vulnerabilities exist when using timing-attack in node applications

Implement one-way in vue component delivery object Binding, how to do it?

How to use TypeScript methods in Vue components (detailed tutorial)

The above is the detailed content of Detailed explanation of how to implement vuex (detailed tutorial). For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn